Abstract

This report explores the relationships between various factors influencing student performance, using exploratory data analysis (EDA) to identify key trends and correlations. The analysis focuses on variables such as study habits, access to resources, parental involvement, and environmental factors, and how they impact final exam scores. Insights gained from the data will inform recommendations aimed at improving academic outcomes for students.

Data Source

The dataset was sourced from Kaggle under the CC0 1.0 universal “No Copyright” license. We are free to copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission. Learn more about this license here here.

URL for data in Kaggle: Student Performance Factors Dataset

Import and View Data

student_data <- read.csv('../data/StudentPerformanceFactors.csv', header = TRUE)
student_data    # Display the dataset

Summary Statistics

# Summary statistics for all variables
summary(student_data)   # Summary statistics for all variables
 Hours_Studied     Attendance     Parental_Involvement Access_to_Resources
 Min.   : 1.00   Min.   : 60.00   Length:6607          Length:6607        
 1st Qu.:16.00   1st Qu.: 70.00   Class :character     Class :character   
 Median :20.00   Median : 80.00   Mode  :character     Mode  :character   
 Mean   :19.98   Mean   : 79.98                                           
 3rd Qu.:24.00   3rd Qu.: 90.00                                           
 Max.   :44.00   Max.   :100.00                                           
 Extracurricular_Activities  Sleep_Hours     Previous_Scores 
 Length:6607                Min.   : 4.000   Min.   : 50.00  
 Class :character           1st Qu.: 6.000   1st Qu.: 63.00  
 Mode  :character           Median : 7.000   Median : 75.00  
                            Mean   : 7.029   Mean   : 75.07  
                            3rd Qu.: 8.000   3rd Qu.: 88.00  
                            Max.   :10.000   Max.   :100.00  
 Motivation_Level   Internet_Access    Tutoring_Sessions Family_Income     
 Length:6607        Length:6607        Min.   :0.000     Length:6607       
 Class :character   Class :character   1st Qu.:1.000     Class :character  
 Mode  :character   Mode  :character   Median :1.000     Mode  :character  
                                       Mean   :1.494                       
                                       3rd Qu.:2.000                       
                                       Max.   :8.000                       
 Teacher_Quality    School_Type        Peer_Influence     Physical_Activity
 Length:6607        Length:6607        Length:6607        Min.   :0.000    
 Class :character   Class :character   Class :character   1st Qu.:2.000    
 Mode  :character   Mode  :character   Mode  :character   Median :3.000    
                                                          Mean   :2.968    
                                                          3rd Qu.:4.000    
                                                          Max.   :6.000    
 Learning_Disabilities Parental_Education_Level Distance_from_Home
 Length:6607           Length:6607              Length:6607       
 Class :character      Class :character         Class :character  
 Mode  :character      Mode  :character         Mode  :character  
                                                                  
                                                                  
                                                                  
    Gender            Exam_Score    
 Length:6607        Min.   : 55.00  
 Class :character   1st Qu.: 65.00  
 Mode  :character   Median : 67.00  
                    Mean   : 67.24  
                    3rd Qu.: 69.00  
                    Max.   :101.00  
head(student_data)      # Display the first few rows of the dataset
str(student_data)       # Structure of the dataset
'data.frame':   6607 obs. of  20 variables:
 $ Hours_Studied             : int  23 19 24 29 19 19 29 25 17 23 ...
 $ Attendance                : int  84 64 98 89 92 88 84 78 94 98 ...
 $ Parental_Involvement      : chr  "Low" "Low" "Medium" "Low" ...
 $ Access_to_Resources       : chr  "High" "Medium" "Medium" "Medium" ...
 $ Extracurricular_Activities: chr  "No" "No" "Yes" "Yes" ...
 $ Sleep_Hours               : int  7 8 7 8 6 8 7 6 6 8 ...
 $ Previous_Scores           : int  73 59 91 98 65 89 68 50 80 71 ...
 $ Motivation_Level          : chr  "Low" "Low" "Medium" "Medium" ...
 $ Internet_Access           : chr  "Yes" "Yes" "Yes" "Yes" ...
 $ Tutoring_Sessions         : int  0 2 2 1 3 3 1 1 0 0 ...
 $ Family_Income             : chr  "Low" "Medium" "Medium" "Medium" ...
 $ Teacher_Quality           : chr  "Medium" "Medium" "Medium" "Medium" ...
 $ School_Type               : chr  "Public" "Public" "Public" "Public" ...
 $ Peer_Influence            : chr  "Positive" "Negative" "Neutral" "Negative" ...
 $ Physical_Activity         : int  3 4 4 4 4 3 2 2 1 5 ...
 $ Learning_Disabilities     : chr  "No" "No" "No" "No" ...
 $ Parental_Education_Level  : chr  "High School" "College" "Postgraduate" "High School" ...
 $ Distance_from_Home        : chr  "Near" "Moderate" "Near" "Moderate" ...
 $ Gender                    : chr  "Male" "Female" "Male" "Male" ...
 $ Exam_Score                : int  67 61 74 71 70 71 67 66 69 72 ...
sum(is.na(student_data))    # Check for missing values
[1] 0

Data Cleaning

We now check whether the dataset contains any missing values and remove them if necessary.

# Check missing values in each column
colSums(is.na(student_data))
             Hours_Studied                 Attendance 
                         0                          0 
      Parental_Involvement        Access_to_Resources 
                         0                          0 
Extracurricular_Activities                Sleep_Hours 
                         0                          0 
           Previous_Scores           Motivation_Level 
                         0                          0 
           Internet_Access          Tutoring_Sessions 
                         0                          0 
             Family_Income            Teacher_Quality 
                         0                          0 
               School_Type             Peer_Influence 
                         0                          0 
         Physical_Activity      Learning_Disabilities 
                         0                          0 
  Parental_Education_Level         Distance_from_Home 
                         0                          0 
                    Gender                 Exam_Score 
                         0                          0 

We can see that there are no missing values in the dataset.

We now check the unique values in each categorical column to identify any inconsistencies.

# Unique values in each categorical column
lapply(student_data[, sapply(student_data, is.character)], unique)
$Parental_Involvement
[1] "Low"    "Medium" "High"  

$Access_to_Resources
[1] "High"   "Medium" "Low"   

$Extracurricular_Activities
[1] "No"  "Yes"

$Motivation_Level
[1] "Low"    "Medium" "High"  

$Internet_Access
[1] "Yes" "No" 

$Family_Income
[1] "Low"    "Medium" "High"  

$Teacher_Quality
[1] "Medium" "High"   "Low"    ""      

$School_Type
[1] "Public"  "Private"

$Peer_Influence
[1] "Positive" "Negative" "Neutral" 

$Learning_Disabilities
[1] "No"  "Yes"

$Parental_Education_Level
[1] "High School"  "College"      "Postgraduate" ""            

$Distance_from_Home
[1] "Near"     "Moderate" "Far"      ""        

$Gender
[1] "Male"   "Female"
Low
Medium
High
High
Medium
Low
No
Yes
Low
Medium
High
Yes
No
Low
Medium
High
Medium
High
Low
Public
Private
Positive
Negative
Neutral
No
Yes
High School
College
Postgraduate
Near
Moderate
Far
Male
Female

From the results above we can Teacher_Quality, Parental_Education_Level and Distance_from_Home have missing values. We will now investigate further to see exactly what these missing values are.

# Check for missing values in Teacher_Quality
teacher_quality_missing <- student_data[student_data$Teacher_Quality == "",]
teacher_quality_missing
nrow(teacher_quality_missing)
[1] 78

We can see that only 78 rows have missing values in the Teacher_Quality column. We will now investigate the Parental_Education_Level column.

# Check for missing values in Parental_Education_Level
parental_education_level_missing <- student_data[student_data$Parental_Education_Level == "",]
parental_education_level_missing
nrow(parental_education_level_missing)
[1] 90

We can see that 90 rows have missing values in the Parental_Education_Level column. We will now investigate the Distance_from_Home column.

# Check for missing values in Distance_from_Home
distance_from_home_missing <- student_data[student_data$Distance_from_Home == "",]
distance_from_home_missing
nrow(distance_from_home_missing)
[1] 67

We can see that 67 rows have missing values in the Distance_from_Home column. All the missing values combined make up less than 10% of the dataset. We will remove these rows from the dataset.

# Remove rows with missing values
student_data <- subset(student_data, Teacher_Quality != "" & Parental_Education_Level != "" & Distance_from_Home != "")

# Check for missing values
lapply(student_data[, sapply(student_data, is.character)], unique)
$Parental_Involvement
[1] "Low"    "Medium" "High"  

$Access_to_Resources
[1] "High"   "Medium" "Low"   

$Extracurricular_Activities
[1] "No"  "Yes"

$Motivation_Level
[1] "Low"    "Medium" "High"  

$Internet_Access
[1] "Yes" "No" 

$Family_Income
[1] "Low"    "Medium" "High"  

$Teacher_Quality
[1] "Medium" "High"   "Low"   

$School_Type
[1] "Public"  "Private"

$Peer_Influence
[1] "Positive" "Negative" "Neutral" 

$Learning_Disabilities
[1] "No"  "Yes"

$Parental_Education_Level
[1] "High School"  "College"      "Postgraduate"

$Distance_from_Home
[1] "Near"     "Moderate" "Far"     

$Gender
[1] "Male"   "Female"
Low
Medium
High
High
Medium
Low
No
Yes
Low
Medium
High
Yes
No
Low
Medium
High
Medium
High
Low
Public
Private
Positive
Negative
Neutral
No
Yes
High School
College
Postgraduate
Near
Moderate
Far
Male
Female

We now investigate the dependent variable, Final_Exam_Score, to identify any outliers.

# Outliers in Final_Exam_Score
outliers_in_exam_score <- student_data[student_data$Exam_Score > 100,]
outliers_in_exam_score
nrow(outliers_in_exam_score)
[1] 1

We can see that only 1 student got exam score of 101 which is an outlier. We will remove this row from the dataset.

# Remove outliers
student_data <- subset(student_data, Exam_Score <= 100)

Now that the data has been cleaned, we can proceed with the exploratory data analysis.

Distribution of Final Exam Scores

Distribution of Final Exam Scores (Without Considering Other Factors)

Here we will explore the distribution of final exam scores among students with without considering other factors. To find our the distribution of final exam scores, we first need to sample the data and plot a histogram.

# Sample the data
set.seed(123)
exam_score_sample <- student_data$Exam_Score[sample(nrow(student_data), 100)]
exam_score_sample
  [1] 66 70 72 68 62 69 72 66 58 69 63 67 70 64 65 70 75 70 69 69 68 63 75 69 68
 [26] 66 68 70 69 64 60 67 66 70 69 65 65 69 69 66 64 64 66 66 66 72 61 71 66 65
 [51] 63 69 70 73 66 70 64 68 71 69 63 68 63 65 70 66 71 71 87 72 67 66 71 64 67
 [76] 63 72 64 68 66 75 70 64 67 65 66 63 69 68 65 68 65 61 71 69 68 66 61 59 65
# Plot histogram
hist(exam_score_sample, main = "Distribution of Final Exam Scores", xlab = "Final Exam Score", col = "skyblue", border = "black")

From the histogram, we can see that the distribution of final exam scores is approximately normal. We now plot a boxplot to visualize the spread of scores and identify any outliers.

# Boxplot of final exam scores
boxplot(exam_score_sample, main = "Boxplot of Final Exam Scores", col = "skyblue", border = "black")

The boxplot shows that the distribution of final exam scores is centered around the median, with a few outliers on the lower end of the scale. Now we use numerical methods to confirm the normality of the distribution.

# Shapiro-Wilk test for normality
shapiro.test(exam_score_sample)

    Shapiro-Wilk normality test

data:  exam_score_sample
W = 0.92839, p-value = 4.035e-05

The Shapiro-Wilk test confirms that the distribution of final exam scores is not normal, with a p-value less than 0.05.

Distribution of Final Exam Scores (Parental_Involvement Category)

Next, we explore the distribution of final exam scores based on parental involvement levels. We will create a boxplot to compare the scores of students with different levels of parental involvement.

# Sample the data
high_parental_involvement <- student_data$Exam_Score[student_data$Parental_Involvement == "High"][sample(sum(student_data$Parental_Involvement == "High"), 100)]
medium_parental_involvement <- student_data$Exam_Score[student_data$Parental_Involvement == "Medium"][sample(sum(student_data$Parental_Involvement == "Medium"), 100)]
low_parental_involvement <- student_data$Exam_Score[student_data$Parental_Involvement == "Low"][sample(sum(student_data$Parental_Involvement == "Low"), 100)]

# Histogram of final exam scores by parental involvement
par(mfrow = c(1, 3))
hist(high_parental_involvement, main = "High Parental Involvement", xlab = "Final Exam Score", col = "skyblue", border = "black")
hist(medium_parental_involvement, main = "Medium Parental Involvement", xlab = "Final Exam Score", col = "skyblue", border = "black")
hist(low_parental_involvement, main = "Low Parental Involvement", xlab = "Final Exam Score", col = "skyblue", border = "black")

The three histograms show the distribution of final exam scores for students with high, medium, and low levels of parental involvement. We can see that the distribution of the scores seems to be similar across all three categories. They seem to follow a normal distribution, with a slight skew towards higher scores for students with high parental involvement. We now use numerical methods to confirm the normality of the distributions.

# Shapiro-Wilk test for normality
shapiro.test(high_parental_involvement)

    Shapiro-Wilk normality test

data:  high_parental_involvement
W = 0.97588, p-value = 0.06325
shapiro.test(medium_parental_involvement)

    Shapiro-Wilk normality test

data:  medium_parental_involvement
W = 0.97777, p-value = 0.08891
shapiro.test(low_parental_involvement)

    Shapiro-Wilk normality test

data:  low_parental_involvement
W = 0.98902, p-value = 0.5864

The Shapiro-Wilk test confirms that the distributions of final exam scores for all students with of parental involvement are approximately normal, with p-values greater than 0.05.

Distribution of Final Exam Scores (Access_to_Resources Category)

Next, we explore the distribution of final exam scores based on access to resources. We will create a boxplot to compare the scores of students with different levels of access to resources.

# Sample the data
high_access_to_resources <- student_data$Exam_Score[student_data$Access_to_Resources == "High"][sample(sum(student_data$Access_to_Resources == "High"), 100)]
medium_access_to_resources <- student_data$Exam_Score[student_data$Access_to_Resources == "Medium"][sample(sum(student_data$Access_to_Resources == "Medium"), 100)]
low_access_to_resources <- student_data$Exam_Score[student_data$Access_to_Resources == "Low"][sample(sum(student_data$Access_to_Resources == "Low"), 100)]

# Histogram of final exam scores by access to resources
par(mfrow = c(1, 3))
hist(high_access_to_resources, main = "High Access to Resources", xlab = "Final Exam Score", col = "skyblue", border = "black")
hist(medium_access_to_resources, main = "Medium Access to Resources", xlab = "Final Exam Score", col = "skyblue", border = "black")
hist(low_access_to_resources, main = "Low Access to Resources", xlab = "Final Exam Score", col = "skyblue", border = "black")

plot(density(low_access_to_resources), main = "Low Access to Resources", xlab = "Final Exam Score", col = "skyblue")
plot(density(medium_access_to_resources), main = "Medium Access to Resources", xlab = "Final Exam Score", col = "skyblue")
plot(density(high_access_to_resources), main = "High Access to Resources", xlab = "Final Exam Score", col = "skyblue")

The histograms and density plots show the distribution of final exam scores for students with high, medium, and low levels of access to resources. The distributions seem to be similar across all three categories, with a slight skew towards higher scores for students with high access to resources. We will now use numerical methods to confirm the normality of the distributions.

# Shapiro-Wilk test for normality
shapiro.test(high_access_to_resources)

    Shapiro-Wilk normality test

data:  high_access_to_resources
W = 0.97748, p-value = 0.0844
shapiro.test(medium_access_to_resources)

    Shapiro-Wilk normality test

data:  medium_access_to_resources
W = 0.97329, p-value = 0.03968
shapiro.test(low_access_to_resources)

    Shapiro-Wilk normality test

data:  low_access_to_resources
W = 0.97248, p-value = 0.0343

The Shapiro-Wilk test confirms that the distributions of final exam scores for students with high resources are approximately normal, with a p-value greater than 0.05. However, the distributions for students with medium and low resources are slightly skewed, with p-values less than 0.05. This conclude that the distribution of final exam scores for students with high resources is normal, while the distributions for students with medium and low resources are slightly skewed.

Distribution of Final Exam Scores (Extracurricular_Activities Category)

Next, we explore the distribution of final exam scores based on participation in extracurricular activities. We will create a boxplot to compare the scores of students who participate in extracurricular activities and those who do not.

# Sample the data
participate_extracurricular <- student_data$Exam_Score[student_data$Extracurricular_Activities == "Yes"][sample(sum(student_data$Extracurricular_Activities == "Yes"), 100)]
do_not_participate_extracurricular <- student_data$Exam_Score[student_data$Extracurricular_Activities == "No"][sample(sum(student_data$Extracurricular_Activities == "No"), 100)]

# Boxplot of final exam scores by extracurricular activities
boxplot(student_data$Exam_Score ~ student_data$Extracurricular_Activities, main = "Final Exam Scores by Extracurricular Activities", xlab = "Extracurricular Activities", ylab = "Final Exam Score", col = "skyblue", border = "black")

The boxplot shows that students who participate in extracurricular activities tend to have higher final exam scores compared to those who do not. Now we will visualize the distribution of scores for both groups using histograms.

# Histogram of final exam scores by extracurricular activities
par(mfrow = c(1, 2))
hist(participate_extracurricular, main = "Extracurricular Activities", xlab = "Final Exam Score", col = "skyblue", border = "black")
hist(do_not_participate_extracurricular, main = "No Extracurricular Activities", xlab = "Final Exam Score", col = "skyblue", border = "black")

Both histograms show normal distributions of final exam scores for students who participate in extracurricular activities and those who do not. We will now use numerical methods to confirm the normality of the distributions.

# Shapiro-Wilk test for normality
shapiro.test(participate_extracurricular)

    Shapiro-Wilk normality test

data:  participate_extracurricular
W = 0.97923, p-value = 0.1158
shapiro.test(do_not_participate_extracurricular)

    Shapiro-Wilk normality test

data:  do_not_participate_extracurricular
W = 0.98142, p-value = 0.1712

The Shapiro-Wilk test confirms that both distributions of final exam scores for students who participate in extracurricular activities and those who do not are approximately normal, with p-values greater than 0.05.

Distribution of Final Exam Scores (Motivation_Level Category)

Next we explore the distribution of final exam scores based on motivation levels. We will create a histogram to compare the scores of students with different motivation levels.

# Smaple Data
high_motivation <- student_data$Exam_Score[student_data$Motivation_Level == "High"][sample(sum(student_data$Motivation_Level == "High"), 100)]
medium_motivation <- student_data$Exam_Score[student_data$Motivation_Level == "High"][sample(sum(student_data$Motivation_Level == "Medium"), 100)]
low_motivation <- student_data$Exam_Score[student_data$Motivation_Level == "High"][sample(sum(student_data$Motivation_Level == "Low"), 100)]

# Histogram of final exam scores by motivation level
par(mfrow = c(1, 3))
hist(high_motivation, main = "High Motivation Level", xlab = "Final Exam Score", col = "skyblue", border = "black")
hist(medium_motivation, main = "Medium Motivation Level", xlab = "Final Exam Score", col = "skyblue", border = "black")
hist(low_motivation, main = "Low Motivation Level", xlab = "Final Exam Score", col = "skyblue", border = "black")

  • High Motivation Level: The distribution is fairly concentrated, with most scores clustered around 65-75. The scores are tightly packed showing a narrower spread. A significant number of students scored within this range indicating a more consistent performance.
  • Medium Motivation Level: The distribution is more spread out compared to the “High Motivation” group, with scores roughly between 62 and 74. This indicates a moderate level of variability in the scores. The frequency of scores is lower in each bin compared to the high motivation group, possibly reflecting a smaller group size or less uniform performance.
  • Low Motivation Level: The distribution appears skewed toward the lower end, with a noticeable cluster around 60–70. The scores have a wider spread, extending even beyond 85, though with fewer students achieving those high scores. Many students scored toward the lower end of the distribution, suggesting less effective exam performance overall.

Higher motivation levels correlate with more consistent and concentrated exam scores around a central range. Lower motivation levels are associated with greater variability and more scores clustering in the lower range. Motivation level seems to have a strong influence on exam performance, with higher motivation linked to better and more uniform outcomes.

# Shapiro-Wilk test for normality
shapiro.test(high_motivation)

    Shapiro-Wilk normality test

data:  high_motivation
W = 0.94412, p-value = 0.0003468
shapiro.test(medium_motivation)

    Shapiro-Wilk normality test

data:  medium_motivation
W = 0.94732, p-value = 0.07268
shapiro.test(low_motivation)

    Shapiro-Wilk normality test

data:  low_motivation
W = 0.83108, p-value = 5.376e-07

The Shapiro-Wilk test confirms that the distributions of final exam scores for students with medium motivation levels are approximately normal, with p-value greater than 0.05. However, the distribution for students with high and low motivation levels is slightly skewed, with a p-value less than 0.05.

Distribution of Final Exam Scores (Internet_Access Category)

Next, we explore the distribution of final exam scores based on internet access. We will create a boxplot to compare the scores of students with and without internet access.

# Sample the data
internet_access <- student_data$Exam_Score[student_data$Internet_Access == "Yes"][sample(sum(student_data$Internet_Access == "Yes"), 100)]
no_internet_access <- student_data$Exam_Score[student_data$Internet_Access == "No"][sample(sum(student_data$Internet_Access == "No"), 100)]

# Histogram of final exam scores by internet access
par(mfrow = c(1, 2))
hist(internet_access, main = "Internet Access", xlab = "Final Exam Score", col = "skyblue", border = "black")
hist(no_internet_access, main = "No Internet Access", xlab = "Final Exam Score", col = "skyblue", border = "black")

  • Internet Access: The distribution appears fairly symmetric, with most scores clustered between 63 and 70. The mode or most frequent score seems to fall around 65-68. Scores are concentrated between 60 and 70 , with few below or above this range. the histogram shows a moderate spread of scores, indicating consistent performance among students.
  • No Internet Access: This distribution is slightly skewed, with scores primarily clustered around 65 and extending toward 70. There are some outliers beyond 75. The highest frequency occurs around 65. Scores are more widely distributed compared to the Internet Access group, with some students scoring as low as 55 and others exceeding 80. The group is larger, as seen by the higher frequency values (bars).
# Shapiro-Wilk test for normality
shapiro.test(internet_access)

    Shapiro-Wilk normality test

data:  internet_access
W = 0.96856, p-value = 0.01718
shapiro.test(no_internet_access)

    Shapiro-Wilk normality test

data:  no_internet_access
W = 0.93958, p-value = 0.0001819

The Shapiro-Wilk test confirms that the distribution of final exam scores for students with and without internet access is not normal, with a p-value less than 0.05.

Summary of Distribution Analysis

In summary, the analysis of the distribution of final exam scores and study hours across various categories such as parental involvement, access to resources, extracurricular activities, motivation levels, internet access, family income, teacher quality, school type, peer influence, learning disabilities, parental education levels, distance from home to school, and gender shows no significant differences. The distributions are approximately normal in most cases, with a few exceptions where the distributions are slightly skewed. Overall, these factors do not have a significant impact on the final exam scores or the number of hours students study per week.

Average number of hours students study per week

Average Number of Hours Students Study per Week (Without Considering Other Factors)

Next, we explore the average number of hours students study per week without considering other factors.

# Summary statistics for study hours
summary(student_data$Hours_Studied)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   1.00   16.00   20.00   19.98   24.00   44.00 

The summary statistics show that the average number of hours students study per week is approximately 19.98 hours. We will now visualize the distribution of study hours using a histogram.

# Histogram of study hours
hist(student_data$Hours_Studied, main = "Distribution of Study Hours", xlab = "Study Hours", col = "skyblue", border = "black")

The distribution of study hours is approximately normal. We will now use numerical methods to confirm the normality of the distribution.

# Shapiro-Wilk test for normality
sample_hours_studied <- student_data$Hours_Studied[sample(nrow(student_data), 100)]
shapiro.test(sample_hours_studied)

    Shapiro-Wilk normality test

data:  sample_hours_studied
W = 0.99057, p-value = 0.7103

The p-value is greater than 0.05, indicating that the distribution of study hours is approximately normal.

Average Number of Hours Students Study per Week (Parental_Involvement Category)

Next, we will explore the average number of hours students study per week based on parental involvement levels.

# Summary statistics for study hours by parental involvement
summary(student_data$Hours_Studied[student_data$Parental_Involvement == "High"])
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   1.00   16.00   20.00   19.86   24.00   44.00 
summary(student_data$Hours_Studied[student_data$Parental_Involvement == "Medium"])
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   1.00   16.00   20.00   19.99   24.00   39.00 
summary(student_data$Hours_Studied[student_data$Parental_Involvement == "Low"])
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   2.00   16.00   20.00   20.11   24.00   38.00 

The summary statistics of the average number of hours students study per week based on parental involvement levels do not show significant differences. We will now use ANOVA to test for differences in study hours based on parental involvement levels. But first, we need to check the assumptions of ANOVA.

# Sample the data
high_parental_involvement <- student_data$Hours_Studied[student_data$Parental_Involvement == "High"][sample(sum(student_data$Parental_Involvement == "High"), 100)]
medium_parental_involvement <- student_data$Hours_Studied[student_data$Parental_Involvement == "Medium"][sample(sum(student_data$Parental_Involvement == "Medium"), 100)]
low_parental_involvement <- student_data$Hours_Studied[student_data$Parental_Involvement == "Low"][sample(sum(student_data$Parental_Involvement == "Low"), 100)]

# Histogram of study hours by parental involvement
par(mfrow = c(1, 3))
hist(high_parental_involvement, main = "High Parental Involvement", xlab = "Study Hours", col = "skyblue", border = "black")
hist(medium_parental_involvement, main = "Medium Parental Involvement", xlab = "Study Hours", col = "skyblue", border = "black")
hist(low_parental_involvement, main = "Low Parental Involvement", xlab = "Study Hours", col = "skyblue", border = "black")

# Check assumptions of ANOVA
shapiro.test(high_parental_involvement)

    Shapiro-Wilk normality test

data:  high_parental_involvement
W = 0.9827, p-value = 0.2145
shapiro.test(medium_parental_involvement)

    Shapiro-Wilk normality test

data:  medium_parental_involvement
W = 0.99085, p-value = 0.7331
shapiro.test(low_parental_involvement)

    Shapiro-Wilk normality test

data:  low_parental_involvement
W = 0.986, p-value = 0.3737

Both the histograms and the Shapiro-Wilk test show that the distribution of study hours is approximately normal for all students. We will now use ANOVA to test for differences in study hours based on parental involvement levels.

# ANOVA test for study hours by parental involvement
anova_parental_involvement <- aov(Hours_Studied ~ Parental_Involvement, data = student_data)
summary(anova_parental_involvement)
                       Df Sum Sq Mean Sq F value Pr(>F)
Parental_Involvement    2     49   24.44   0.682  0.506
Residuals            6374 228362   35.83               

The ANOVA test shows that there is no significant difference in the average number of hours students study per week based on parental involvement levels, with a p-value greater than 0.05. This indicates that parental involvement does not have a significant impact on the number of hours students study per week.

Average Number of Hours Students Study per Week (Access_to_Resources Category)

We now explore the average number of hours students study per week based on access to resources.

summary(student_data$Hours_Studied[student_data$Access_to_Resources == "High"])
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   1.00   16.00   20.00   20.02   24.00   39.00 
summary(student_data$Hours_Studied[student_data$Access_to_Resources == "Medium"])
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
    1.0    16.0    20.0    19.9    24.0    43.0 
summary(student_data$Hours_Studied[student_data$Access_to_Resources == "Low"])
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   2.00   16.00   20.00   20.12   24.00   44.00 

The summary statistics of the average number of hours students study per week based on access to resources do not show significant differences. We will now use ANOVA to test for differences in study hours based on access to resources. But first, we need to check the assumptions of ANOVA.

# Sample the data
high_access_to_resources <- student_data$Hours_Studied[student_data$Access_to_Resources == "High"][sample(sum(student_data$Access_to_Resources == "High"), 100)]
medium_access_to_resources <- student_data$Hours_Studied[student_data$Access_to_Resources == "Medium"][sample(sum(student_data$Access_to_Resources == "Medium"), 100)]
low_access_to_resources <- student_data$Hours_Studied[student_data$Access_to_Resources == "Low"][sample(sum(student_data$Access_to_Resources == "Low"), 100)]

# Histogram of study hours by access to resources
par(mfrow = c(1, 3))
hist(high_access_to_resources, main = "High Access to Resources", xlab = "Study Hours", col = "skyblue", border = "black")
hist(medium_access_to_resources, main = "Medium Access to Resources", xlab = "Study Hours", col = "skyblue", border = "black")
hist(low_access_to_resources, main = "Low Access to Resources", xlab = "Study Hours", col = "skyblue", border = "black")

# Check assumptions of ANOVA
shapiro.test(high_access_to_resources)

    Shapiro-Wilk normality test

data:  high_access_to_resources
W = 0.98025, p-value = 0.139
shapiro.test(medium_access_to_resources)

    Shapiro-Wilk normality test

data:  medium_access_to_resources
W = 0.96582, p-value = 0.01068
shapiro.test(low_access_to_resources)

    Shapiro-Wilk normality test

data:  low_access_to_resources
W = 0.97123, p-value = 0.02747

Both the histograms and the Shapiro-Wilk test show that the distribution of study hours is approximately normal for all students. We will now use ANOVA to test for differences in study hours based on access to resources.

# ANOVA test for study hours by access to resources
anova_access_to_resources <- aov(Hours_Studied ~ Access_to_Resources, data = student_data)
summary(anova_access_to_resources)
                      Df Sum Sq Mean Sq F value Pr(>F)
Access_to_Resources    2     48   24.12   0.673   0.51
Residuals           6374 228363   35.83               

The ANOVA test shows that there is no significant difference in the average number of hours students study per week based on access to resources, with a p-value greater than 0.05. This indicates that access to resources does not have a significant impact on the number of hours students study per week.

Average Number of Hours Students Study per Week (Extracurricular_Activities Category)

Next, we explore the average number of hours students study per week based on participation in extracurricular activities.

# Summary statistics for study hours by extracurricular activities
summary(student_data$Hours_Studied[student_data$Extracurricular_Activities == "Yes"])
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   1.00   16.00   20.00   19.93   24.00   43.00 
summary(student_data$Hours_Studied[student_data$Extracurricular_Activities == "No"])
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   2.00   16.00   20.00   20.04   24.00   44.00 

The summary statistics of the average number of hours students study per week based on participation in extracurricular activities show no significant differences. We will now use t-test to test for differences in study hours based on participation in extracurricular activities. But first, we need to check the assumptions of t-test.

# Sample the data
participate_extracurricular <- student_data$Hours_Studied[student_data$Extracurricular_Activities == "Yes"][sample(sum(student_data$Extracurricular_Activities == "Yes"), 100)]
do_not_participate_extracurricular <- student_data$Hours_Studied[student_data$Extracurricular_Activities == "No"][sample(sum(student_data$Extracurricular_Activities == "No"), 100)]

# Histogram of study hours by extracurricular activities
par(mfrow = c(1, 2))
hist(participate_extracurricular, main = "Extracurricular Activities", xlab = "Study Hours", col = "skyblue", border = "black")
hist(do_not_participate_extracurricular, main = "No Extracurricular Activities", xlab = "Study Hours", col = "skyblue", border = "black")

# Check assumptions of t-test
shapiro.test(participate_extracurricular)

    Shapiro-Wilk normality test

data:  participate_extracurricular
W = 0.98586, p-value = 0.3655
shapiro.test(do_not_participate_extracurricular)

    Shapiro-Wilk normality test

data:  do_not_participate_extracurricular
W = 0.98909, p-value = 0.5916

Both the histograms and the Shapiro-Wilk test show that the distribution of study hours is approximately normal for all students. We will now use t-test to test for differences in study hours based on participation in extracurricular activities.

# t-test test for study hours by extracurricular activities
t.test(participate_extracurricular, do_not_participate_extracurricular)

    Welch Two Sample t-test

data:  participate_extracurricular and do_not_participate_extracurricular
t = -0.99317, df = 197.84, p-value = 0.3218
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -2.5079006  0.8279006
sample estimates:
mean of x mean of y 
    20.29     21.13 

The t-test shows that there is no significant difference in the average number of hours students study per week based on participation in extracurricular activities, with a p-value greater than 0.05. This indicates that participation in extracurricular activities does not have a significant impact on the number of hours students study per week.

Average Number of Hours Students Study per Week (Motivation_Level Category)

Next, we explore the average number of hours students study per week based on motivation levels.

# Summary statistics for study hours by motivation level
summary(student_data$Hours_Studied[student_data$Motivation_Level == "High"])
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   1.00   16.00   20.00   19.75   24.00   39.00 
summary(student_data$Hours_Studied[student_data$Motivation_Level == "Medium"])
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   1.00   16.00   20.00   20.06   24.00   43.00 
summary(student_data$Hours_Studied[student_data$Motivation_Level == "Low"])
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   2.00   16.00   20.00   19.98   24.00   44.00 

The summary statistics of the average number of hours students study per week based on motivation levels show no significant differences. We will now use ANOVA to test for differences in study hours based on motivation levels. But first, we need to check the assumptions of ANOVA.

# Sample the data
high_motivation <- student_data$Hours_Studied[student_data$Motivation_Level == "High"][sample(sum(student_data$Motivation_Level == "High"), 100)]
medium_motivation <- student_data$Hours_Studied[student_data$Motivation_Level == "Medium"][sample(sum(student_data$Motivation_Level == "Medium"), 100)]
low_motivation <- student_data$Hours_Studied[student_data$Motivation_Level == "Low"][sample(sum(student_data$Motivation_Level == "Low"), 100)]

# Histogram of study hours by motivation level
par(mfrow = c(1, 3))
hist(high_motivation, main = "High Motivation Level", xlab = "Study Hours", col = "skyblue", border = "black")
hist(medium_motivation, main = "Medium Motivation Level", xlab = "Study Hours", col = "skyblue", border = "black")
hist(low_motivation, main = "Low Motivation Level", xlab = "Study Hours", col = "skyblue", border = "black")

# Check assumptions of ANOVA
shapiro.test(high_motivation)

    Shapiro-Wilk normality test

data:  high_motivation
W = 0.98676, p-value = 0.4217
shapiro.test(medium_motivation)

    Shapiro-Wilk normality test

data:  medium_motivation
W = 0.9649, p-value = 0.009127
shapiro.test(low_motivation)

    Shapiro-Wilk normality test

data:  low_motivation
W = 0.99065, p-value = 0.717

Shapiro-Wilk test shows that the distribution of study hours of students with medium motivation is not normal, with a p-value less than 0.05. We will now use Kruksal-Wallis test to test for differences in study hours based on motivation levels.

# Kruskal-Wallis test for study hours by motivation level
kruskal.test(Hours_Studied ~ Motivation_Level, data = student_data)

    Kruskal-Wallis rank sum test

data:  Hours_Studied by Motivation_Level
Kruskal-Wallis chi-squared = 2.9587, df = 2, p-value = 0.2278

The Kruskal-Wallis test shows that there is no significant difference in the average number of hours students study per week based on motivation levels, with a p-value greater than 0.05. This indicates that motivation levels do not have a significant impact on the number of hours students study per week.

Average Number of Hours Students Study per Week (Internet Access Category)

Next, we explore the average number of hours students study per week based on internet access.

# Summary statistics for study hours by internet access
summary(student_data$Hours_Studied[student_data$Internet_Access == "Yes"])
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   1.00   16.00   20.00   19.99   24.00   44.00 
summary(student_data$Hours_Studied[student_data$Internet_Access == "No"])
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   4.00   15.00   20.00   19.83   24.00   37.00 

The summary statistics of the average number of hours students study per week based on internet access show no significant differences. We will now use t-test to test for differences in study hours based on internet access. But first, we need to check the assumptions of t-test.

# Sample the data
internet_access <- student_data$Hours_Studied[student_data$Internet_Access == "Yes"][sample(sum(student_data$Internet_Access == "Yes"), 100)]
no_internet_access <- student_data$Hours_Studied[student_data$Internet_Access == "No"][sample(sum(student_data$Internet_Access == "No"), 100)]

# Histogram of study hours by internet access
par(mfrow = c(1, 2))
hist(internet_access, main = "Internet Access", xlab = "Study Hours", col = "skyblue", border = "black")
hist(no_internet_access, main = "No Internet Access", xlab = "Study Hours", col = "skyblue", border = "black")

# Check assumptions of t-test
shapiro.test(internet_access)

    Shapiro-Wilk normality test

data:  internet_access
W = 0.99238, p-value = 0.8479
shapiro.test(no_internet_access)

    Shapiro-Wilk normality test

data:  no_internet_access
W = 0.99029, p-value = 0.6878

Both the histograms and the Shapiro-Wilk test show that the distribution of study hours is approximately normal for all students. We will now use t-test to test for differences in study hours based on internet access.

# t-test test for study hours by internet access
t.test(internet_access, no_internet_access)

    Welch Two Sample t-test

data:  internet_access and no_internet_access
t = -2.2355, df = 197.79, p-value = 0.0265
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -3.7078465 -0.2321535
sample estimates:
mean of x mean of y 
    18.90     20.87 

The p-value is less than 0.05, indicating that there is a significant difference in the average number of hours students study per week based on internet access. This suggests that internet access has a significant impact on the number of hours students study per week.

Average Number of Hours Students Study per Week (Family Income Category)

Next, we explore the average number of hours students study per week based on family income levels.

# Summary statistics for study hours by family income
summary(student_data$Hours_Studied[student_data$Family_Income == "Low"])
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   1.00   16.00   20.00   19.93   24.00   39.00 
summary(student_data$Hours_Studied[student_data$Family_Income == "Medium"])
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   1.00   16.00   20.00   20.07   24.00   44.00 
summary(student_data$Hours_Studied[student_data$Family_Income == "High"])
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   3.00   16.00   20.00   19.89   24.00   39.00 

The summary statistics of the average number of hours students study per week based on family income levels show no significant differences. We will now use ANOVA to test for differences in study hours based on family income levels. But first, we need to check the assumptions of ANOVA.

# Sample the data
low_family_income <- student_data$Hours_Studied[student_data$Family_Income == "Low"][sample(sum(student_data$Family_Income == "Low"), 100)]
medium_family_income <- student_data$Hours_Studied[student_data$Family_Income == "Medium"][sample(sum(student_data$Family_Income == "Medium"), 100)]
high_family_income <- student_data$Hours_Studied[student_data$Family_Income == "High"][sample(sum(student_data$Family_Income == "High"), 100)]

# Histogram of study hours by family income
par(mfrow = c(1, 3))
hist(low_family_income, main = "Low Family Income", xlab = "Study Hours", col = "skyblue", border = "black")
hist(medium_family_income, main = "Medium Family Income", xlab = "Study Hours", col = "skyblue", border = "black")
hist(high_family_income, main = "High Family Income", xlab = "Study Hours", col = "skyblue", border = "black")

# Check assumptions of ANOVA
shapiro.test(low_family_income)

    Shapiro-Wilk normality test

data:  low_family_income
W = 0.99118, p-value = 0.7595
shapiro.test(medium_family_income)

    Shapiro-Wilk normality test

data:  medium_family_income
W = 0.98624, p-value = 0.3883
shapiro.test(high_family_income)

    Shapiro-Wilk normality test

data:  high_family_income
W = 0.98195, p-value = 0.1881

Both the histograms and the Shapiro-Wilk test show that the distribution of study hours is approximately normal for all students. We will now use ANOVA to test for differences in study hours based on family income levels.

# ANOVA test for study hours by family income
anova_family_income <- aov(Hours_Studied ~ Family_Income, data = student_data)
summary(anova_family_income)
                Df Sum Sq Mean Sq F value Pr(>F)
Family_Income    2     35   17.47   0.487  0.614
Residuals     6374 228376   35.83               

The ANOVA test shows that there is no significant difference in the average number of hours students study per week based on family income levels, with a p-value greater than 0.05. This indicates that family income does not have a significant impact on the number of hours students study per week.

Average Number of Hours Students Study per Week (Teacher Quality Category)

Next, we explore the average number of hours students study per week based on teacher quality levels.

# Summary statistics for study hours by teacher quality
summary(student_data$Hours_Studied[student_data$Teacher_Quality == "Low"])
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   4.00   16.00   20.00   20.05   24.00   39.00 
summary(student_data$Hours_Studied[student_data$Teacher_Quality == "Medium"])
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   1.00   16.00   20.00   19.99   24.00   39.00 
summary(student_data$Hours_Studied[student_data$Teacher_Quality == "High"])
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   2.00   16.00   20.00   19.92   24.00   44.00 

The summary statistics of the average number of hours students study per week based on teacher quality levels show no significant differences. We will now use ANOVA to test for differences in study hours based on teacher quality levels. But first, we need to check the assumptions of ANOVA.

# Sample the data
low_teacher_quality <- student_data$Hours_Studied[student_data$Teacher_Quality == "Low"][sample(sum(student_data$Teacher_Quality == "Low"), 100)]
medium_teacher_quality <- student_data$Hours_Studied[student_data$Teacher_Quality == "Medium"][sample(sum(student_data$Teacher_Quality == "Medium"), 100)]
high_teacher_quality <- student_data$Hours_Studied[student_data$Teacher_Quality == "High"][sample(sum(student_data$Teacher_Quality == "High"), 100)]

# Histogram of study hours by teacher quality
par(mfrow = c(1, 3))
hist(low_teacher_quality, main = "Low Teacher Quality", xlab = "Study Hours", col = "skyblue", border = "black")
hist(medium_teacher_quality, main = "Medium Teacher Quality", xlab = "Study Hours", col = "skyblue", border = "black")
hist(high_teacher_quality, main = "High Teacher Quality", xlab = "Study Hours", col = "skyblue", border = "black")

# Check assumptions of ANOVA
shapiro.test(low_teacher_quality)

    Shapiro-Wilk normality test

data:  low_teacher_quality
W = 0.98158, p-value = 0.1763
shapiro.test(medium_teacher_quality)

    Shapiro-Wilk normality test

data:  medium_teacher_quality
W = 0.98216, p-value = 0.1952
shapiro.test(high_teacher_quality)

    Shapiro-Wilk normality test

data:  high_teacher_quality
W = 0.98864, p-value = 0.5568

All three histograms and the Shapiro-Wilk test show that the distribution of study hours is approximately normal for all students. We will now use ANOVA to test for differences in study hours based on teacher quality levels.

# ANOVA test for study hours by teacher quality
anova_teacher_quality <- aov(Hours_Studied ~ Teacher_Quality, data = student_data)
summary(anova_teacher_quality)
                  Df Sum Sq Mean Sq F value Pr(>F)
Teacher_Quality    2     12    5.88   0.164  0.849
Residuals       6374 228400   35.83               

The ANOVA test shows that there is no significant difference in the average number of hours students study per week based on teacher quality levels, with a p-value greater than 0.05. This indicates that teacher quality does not have a significant impact on the number of hours students study per week.

Average Number of Hours Students Study per Week (School Type Category)

Next, we explore the average number of hours students study per week based on school type.

# Summary statistics for study hours by school type
summary(student_data$Hours_Studied[student_data$School_Type == "Public"])
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   1.00   16.00   20.00   19.98   24.00   43.00 
summary(student_data$Hours_Studied[student_data$School_Type == "Private"])
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   1.00   16.00   20.00   19.97   24.00   44.00 

The summary statistics of the average number of hours students study per week based on school type show no significant differences. We will now use t-test to test for differences in study hours based on school type. But first, we need to check the assumptions of t-test.

# Sample the data
public_school <- student_data$Hours_Studied[student_data$School_Type == "Public"][sample(sum(student_data$School_Type == "Public"), 100)]
private_school <- student_data$Hours_Studied[student_data$School_Type == "Private"][sample(sum(student_data$School_Type == "Private"), 100)]

# Histogram of study hours by school type
par(mfrow = c(1, 2))
hist(public_school, main = "Public School", xlab = "Study Hours", col = "skyblue", border = "black")
hist(private_school, main = "Private School", xlab = "Study Hours", col = "skyblue", border = "black")

# Check assumptions of t-test
shapiro.test(public_school)

    Shapiro-Wilk normality test

data:  public_school
W = 0.98459, p-value = 0.2967
shapiro.test(private_school)

    Shapiro-Wilk normality test

data:  private_school
W = 0.98734, p-value = 0.4609

Both histograms and the Shapiro-Wilk test show that the distribution of study hours is approximately normal for all students. We will now use t-test to test for differences in study hours based on school type.

# t-test test for study hours by school type
t.test(public_school, private_school)

    Welch Two Sample t-test

data:  public_school and private_school
t = -0.26017, df = 197.45, p-value = 0.795
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -1.887563  1.447563
sample estimates:
mean of x mean of y 
    19.33     19.55 

The t-test test shows that there is no significant difference in the average number of hours students study per week based on school type, with a p-value greater than 0.05. This indicates that school type does not have a significant impact on the number of hours students study per week.

Average Number of Hours Students Study per Week (Peer Influence Category)

Next, we explore the average number of hours students study per week based on peer influence levels.

# Summary statistics for study hours by peer influence
summary(student_data$Hours_Studied[student_data$Peer_Influence == "Positive"])
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   1.00   16.00   20.00   20.06   24.00   43.00 
summary(student_data$Hours_Studied[student_data$Peer_Influence == "Negative"])
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   1.00   16.00   20.00   19.95   24.00   44.00 
summary(student_data$Hours_Studied[student_data$Peer_Influence == "Neutral"])
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   2.00   16.00   20.00   19.91   24.00   39.00 

The summary statistics of the average number of hours students study per week based on peer influence levels show no significant differences. We will now use ANOVA to test for differences in study hours based on peer influence levels. But first, we need to check the assumptions of ANOVA.

# Sample the data
positive_peer_influence <- student_data$Hours_Studied[student_data$Peer_Influence == "Positive"][sample(sum(student_data$Peer_Influence == "Positive"), 100)]
negative_peer_influence <- student_data$Hours_Studied[student_data$Peer_Influence == "Negative"][sample(sum(student_data$Peer_Influence == "Negative"), 100)]
neutral_peer_influence <- student_data$Hours_Studied[student_data$Peer_Influence == "Neutral"][sample(sum(student_data$Peer_Influence == "Neutral"), 100)]

# Histogram of study hours by peer influence
par(mfrow = c(1, 3))
hist(positive_peer_influence, main = "Positive Peer Influence", xlab = "Study Hours", col = "skyblue", border = "black")
hist(negative_peer_influence, main = "Negative Peer Influence", xlab = "Study Hours", col = "skyblue", border = "black")
hist(neutral_peer_influence, main = "Neutral Peer Influence", xlab = "Study Hours", col = "skyblue", border = "black")

# Check assumptions of ANOVA
shapiro.test(positive_peer_influence)

    Shapiro-Wilk normality test

data:  positive_peer_influence
W = 0.98724, p-value = 0.454
shapiro.test(negative_peer_influence)

    Shapiro-Wilk normality test

data:  negative_peer_influence
W = 0.98803, p-value = 0.5107
shapiro.test(neutral_peer_influence)

    Shapiro-Wilk normality test

data:  neutral_peer_influence
W = 0.97778, p-value = 0.08907

All three histograms and the Shapiro-Wilk test show that the distribution of study hours is approximately normal for all students. We will now use ANOVA to test for differences in study hours based on peer influence levels.

# ANOVA test for study hours by peer influence
anova_peer_influence <- aov(Hours_Studied ~ Peer_Influence, data = student_data)
summary(anova_peer_influence)
                 Df Sum Sq Mean Sq F value Pr(>F)
Peer_Influence    2     29   14.33     0.4   0.67
Residuals      6374 228383   35.83               

The ANOVA test shows that there is no significant difference in the average number of hours students study per week based on peer influence levels, with a p-value greater than 0.05. This indicates that peer influence does not have a significant impact on the number of hours students study per week.

Average Number of Hours Students Study per Week (Learning Disability Category)

Next, we explore the average number of hours students study per week based on learning disability.

# Summary statistics for study hours by learning disability
summary(student_data$Hours_Studied[student_data$Learning_Disabilities == "Yes"])
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   4.00   16.00   20.00   19.73   24.00   35.00 
summary(student_data$Hours_Studied[student_data$Learning_Disabilities == "No"])
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
      1      16      20      20      24      44 

The summary statistics of the average number of hours students study per week based on learning disability show no significant differences. We will now use t-test to test for differences in study hours based on learning disability. But first, we need to check the assumptions of t-test.

# Sample the data
learning_disabilities <- student_data$Hours_Studied[student_data$Learning_Disabilities == "Yes"][sample(sum(student_data$Learning_Disabilities == "Yes"), 100)]
no_learning_disabilities <- student_data$Hours_Studied[student_data$Learning_Disabilities == "No"][sample(sum(student_data$Learning_Disabilities == "No"), 100)]

# Histogram of study hours by learning disability
par(mfrow = c(1, 2))
hist(learning_disabilities, main = "Learning Disabilities", xlab = "Study Hours", col = "skyblue", border = "black")
hist(no_learning_disabilities, main = "No Learning Disabilities", xlab = "Study Hours", col = "skyblue", border = "black")

# Check assumptions of t-test
shapiro.test(learning_disabilities)

    Shapiro-Wilk normality test

data:  learning_disabilities
W = 0.98009, p-value = 0.135
shapiro.test(no_learning_disabilities)

    Shapiro-Wilk normality test

data:  no_learning_disabilities
W = 0.97305, p-value = 0.03802

The Shapiro-Wilk test shows that the distribution of study hours is approximately normal for students with learning disabilities, with a p-value greater than 0.05. However, the distribution for students without learning disabilities is slightly skewed, with a p-value less than 0.05. We will now use wilcoxon rank sum test to test for differences in study hours based on learning disability.

# Wilcoxon rank sum test for study hours by learning disability
wilcox.test(learning_disabilities, no_learning_disabilities)

    Wilcoxon rank sum test with continuity correction

data:  learning_disabilities and no_learning_disabilities
W = 5135, p-value = 0.742
alternative hypothesis: true location shift is not equal to 0

The t-test test shows that there is no significant difference in the average number of hours students study per week based on learning disability, with a p-value greater than 0.05. This indicates that learning disabilities do not have a significant impact on the number of hours students study per week.

Average Number of Hours Students Study per Week (Parental Education Level Category)

Next, we explore the average number of hours students study per week based on parental education levels.

# Summary statistics for study hours by parental education level
summary(student_data$Hours_Studied[student_data$Parental_Education_Level == "High School"])
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   1.00   16.00   20.00   20.05   24.00   44.00 
summary(student_data$Hours_Studied[student_data$Parental_Education_Level == "College"])
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   1.00   16.00   20.00   19.87   24.00   39.00 
summary(student_data$Hours_Studied[student_data$Parental_Education_Level == "Postgraduate"])
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   3.00   16.00   20.00   19.97   24.00   39.00 

The summary statistics of the average number of hours students study per week based on parental education levels show no significant differences. We will now use ANOVA to test for differences in study hours based on parental education levels. But first, we need to check the assumptions of ANOVA.

# Sample the data
high_school_education <- student_data$Hours_Studied[student_data$Parental_Education_Level == "High School"][sample(sum(student_data$Parental_Education_Level == "High School"), 100)]
college_education <- student_data$Hours_Studied[student_data$Parental_Education_Level == "College"][sample(sum(student_data$Parental_Education_Level == "College"), 100)]
postgraduate_education <- student_data$Hours_Studied[student_data$Parental_Education_Level == "Postgraduate"][sample(sum(student_data$Parental_Education_Level == "Postgraduate"), 100)]

# Histogram of study hours by parental education level
par(mfrow = c(1, 3))
hist(high_school_education, main = "High School Education", xlab = "Study Hours", col = "skyblue", border = "black")
hist(college_education, main = "College Education", xlab = "Study Hours", col = "skyblue", border = "black")
hist(postgraduate_education, main = "Postgraduate Education", xlab = "Study Hours", col = "skyblue", border = "black")

# Check assumptions of ANOVA
shapiro.test(high_school_education)

    Shapiro-Wilk normality test

data:  high_school_education
W = 0.98413, p-value = 0.2746
shapiro.test(college_education)

    Shapiro-Wilk normality test

data:  college_education
W = 0.97967, p-value = 0.1253
shapiro.test(postgraduate_education)

    Shapiro-Wilk normality test

data:  postgraduate_education
W = 0.98131, p-value = 0.168

All three histograms and the Shapiro-Wilk test show that the distribution of study hours is approximately normal for all students. We will now use ANOVA to test for differences in study hours based on parental education levels.

# ANOVA test for study hours by parental education level
anova_parental_education_level <- aov(Hours_Studied ~ Parental_Education_Level, data = student_data)
summary(anova_parental_education_level)
                           Df Sum Sq Mean Sq F value Pr(>F)
Parental_Education_Level    2     37   18.71   0.522  0.593
Residuals                6374 228374   35.83               

The ANOVA test shows that there is no significant difference in the average number of hours students study per week based on parental education levels, with a p-value greater than 0.05. This indicates that parental education levels do not have a significant impact on the number of hours students study per week.

Average Number of Hours Students Study per Week (Distance from Home Category)

Next, we explore the average number of hours students study per week based on the distance from home to school.

# Summary statistics for study hours by distance from home (Near, Moderate, Far
summary(student_data$Hours_Studied[student_data$Distance_from_Home == "Near"])
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
    1.0    16.0    20.0    19.9    24.0    43.0 
summary(student_data$Hours_Studied[student_data$Distance_from_Home == "Moderate"])
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   2.00   16.00   20.00   20.05   24.00   44.00 
summary(student_data$Hours_Studied[student_data$Distance_from_Home == "Far"])
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
    3.0    16.0    20.0    20.2    24.0    39.0 

The summary statistics of the average number of hours students study per week based on the distance from home to school show no significant differences. We will now use ANOVA to test for differences in study hours based on the distance from home to school. But first, we need to check the assumptions of ANOVA.

# Sample the data
near_distance <- student_data$Hours_Studied[student_data$Distance_from_Home == "Near"][sample(sum(student_data$Distance_from_Home == "Near"), 100)]
moderate_distance <- student_data$Hours_Studied[student_data$Distance_from_Home == "Moderate"][sample(sum(student_data$Distance_from_Home == "Moderate"), 100)]
far_distance <- student_data$Hours_Studied[student_data$Distance_from_Home == "Far"][sample(sum(student_data$Distance_from_Home == "Far"), 100)]

# Histogram of study hours by distance from home
par(mfrow = c(1, 3))
hist(near_distance, main = "Near Distance from Home", xlab = "Study Hours", col = "skyblue", border = "black")
hist(moderate_distance, main = "Moderate Distance from Home", xlab = "Study Hours", col = "skyblue", border = "black")
hist(far_distance, main = "Far Distance from Home", xlab = "Study Hours", col = "skyblue", border = "black")

# Check assumptions of ANOVA
shapiro.test(near_distance)

    Shapiro-Wilk normality test

data:  near_distance
W = 0.97892, p-value = 0.1094
shapiro.test(moderate_distance)

    Shapiro-Wilk normality test

data:  moderate_distance
W = 0.99076, p-value = 0.7258
shapiro.test(far_distance)

    Shapiro-Wilk normality test

data:  far_distance
W = 0.98969, p-value = 0.6399

All three histograms and the Shapiro-Wilk test show that the distribution of study hours is approximately normal for all students. We will now use ANOVA to test for differences in study hours based on the distance from home to school.

# ANOVA test for study hours by distance from home
anova_distance_from_home <- aov(Hours_Studied ~ Distance_from_Home, data = student_data)
summary(anova_distance_from_home)
                     Df Sum Sq Mean Sq F value Pr(>F)
Distance_from_Home    2     67   33.48   0.934  0.393
Residuals          6374 228344   35.82               

The ANOVA test shows that there is no significant difference in the average number of hours students study per week based on the distance from home to school, with a p-value greater than 0.05. This indicates that the distance from home to school does not have a significant impact on the number of hours students study per week.

Average Number of Hours Students Study per Week (Gender Category)

Finally, we explore the average number of hours students study per week based on gender.

# Summary statistics
summary(student_data$Hours_Studied[student_data$Gender == "Male"])
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   1.00   16.00   20.00   19.94   24.00   39.00 
summary(student_data$Hours_Studied[student_data$Gender == "Female"])
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   1.00   16.00   20.00   20.02   24.00   44.00 

The summary statistics of the average number of hours students study per week based on gender show no significant differences. We will now use ANOVA to test for differences in study hours based on gender. But first, we need to check the assumptions of ANOVA.

# Sample the data
male_data <- student_data$Hours_Studied[student_data$Gender == "Male"][sample(sum(student_data$Gender == "Male"), 100)]
female_data <- student_data$Hours_Studied[student_data$Gender == "Female"][sample(sum(student_data$Gender == "Female"), 100)]

# Histogram
par(mfrow = c(1, 2))
hist(male_data, main = "Male", xlab = "Study Hours", col = "skyblue", border = "black")
hist(female_data, main = "Female", xlab = "Study Hours", col = "skyblue", border = "black")

# Check assumptions of ANOVA
shapiro.test(male_data)

    Shapiro-Wilk normality test

data:  male_data
W = 0.99016, p-value = 0.6773
shapiro.test(female_data)

    Shapiro-Wilk normality test

data:  female_data
W = 0.9903, p-value = 0.6889

Both histograms and the Shapiro-Wilk test show that the distribution of study hours is approximately normal for all students. We will now use ANOVA to test for differences in study hours based gender.

# ANOVA test
anova_gender <- aov(Hours_Studied ~ Gender, data = student_data)
summary(anova_gender)
              Df Sum Sq Mean Sq F value Pr(>F)
Gender         1     11   11.12    0.31  0.577
Residuals   6375 228400   35.83               

The ANOVA test shows that there is no significant difference in the average number of hours students study based on gender.

Summary of Average Number of Hours Students Study per Week

In summary, the average number of hours students study per week is approximately 19.98 hours. There are no significant differences in the average number of hours students study per week based on various factors such as parental involvement, access to resources, extracurricular activities, motivation levels, internet access, family income, teacher quality, school type, peer influence, learning disabilities, parental education levels, distance from home to school, and Gender. This indicates that the number of hours students study per week is consistent across different factors.

The variation in attendance rates across students

Now we analyze the variation in attendance rates across students.

# Sample the data
sample_attendance <- student_data$Attendance[sample(nrow(student_data), 1000)]

# Summary statistics for attendance rates
summary(sample_attendance)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   60.0    70.0    81.0    80.8    92.0   100.0 
# Histogram of attendance rates
hist(sample_attendance, main = "Distribution of Attendance Rates", xlab = "Attendance Rate", col = "skyblue", border = "black")

From the histogram we can see that the distribution of attendance rates is approximately uniform, ranging from approximately 60% to 100%. We can see one slightly higher peak around 70% to 80%. From this we can see that attendance rates are evenly distributed across students. The average attendance rate is approximately 79.75%, which is relatively high. We now investigate the factors that may influence attendance rates.

Attendance Rates by Parental Involvement

We will now explore the attendance rates based on parental involvement levels.

# Summary statistics for attendance rates by parental involvement
summary(student_data$Attendance[student_data$Parental_Involvement == "High"])
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  60.00   70.00   80.00   80.01   90.00  100.00 
summary(student_data$Attendance[student_data$Parental_Involvement == "Medium"])
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   60.0    70.0    80.0    79.9    90.0   100.0 
summary(student_data$Attendance[student_data$Parental_Involvement == "Low"])
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  60.00   70.00   80.00   80.32   91.00  100.00 

The summary statistics of the attendance rates based on parental involvement levels show no significant differences. We will now use ANOVA to test for differences in attendance rates based on parental involvement levels. But first, we need to check the assumptions of ANOVA.

# Sample the data
high_parental_involvement_attendance <- student_data$Attendance[student_data$Parental_Involvement == "High"][sample(sum(student_data$Parental_Involvement == "High"), 100)]
medium_parental_involvement_attendance <- student_data$Attendance[student_data$Parental_Involvement == "Medium"][sample(sum(student_data$Parental_Involvement == "Medium"), 100)]
low_parental_involvement_attendance <- student_data$Attendance[student_data$Parental_Involvement == "Low"][sample(sum(student_data$Parental_Involvement == "Low"), 100)]

# Histogram of attendance rates by parental involvement
par(mfrow = c(1, 3))
hist(high_parental_involvement_attendance, main = "High Parental Involvement", xlab = "Attendance Rate", col = "skyblue", border = "black")
hist(medium_parental_involvement_attendance, main = "Medium Parental Involvement", xlab = "Attendance Rate", col = "skyblue", border = "black")
hist(low_parental_involvement_attendance, main = "Low Parental Involvement", xlab = "Attendance Rate", col = "skyblue", border = "black")

# Check assumptions of ANOVA
shapiro.test(high_parental_involvement_attendance)

    Shapiro-Wilk normality test

data:  high_parental_involvement_attendance
W = 0.9466, p-value = 0.0004986
shapiro.test(medium_parental_involvement_attendance)

    Shapiro-Wilk normality test

data:  medium_parental_involvement_attendance
W = 0.92294, p-value = 2.023e-05
shapiro.test(low_parental_involvement_attendance)

    Shapiro-Wilk normality test

data:  low_parental_involvement_attendance
W = 0.928, p-value = 3.842e-05

All three histograms and the Shapiro-Wilk test show that the distribution of attendance rates is not normal for all students. We will now use Kruksal-Wallis test to test for differences in attendance rates based on parental involvement levels.

# Kruksal-Wallis test
kruskal.test(Attendance ~ Parental_Involvement, data = student_data)

    Kruskal-Wallis rank sum test

data:  Attendance by Parental_Involvement
Kruskal-Wallis chi-squared = 1.2171, df = 2, p-value = 0.5441

The Kruskal-Wallis test shows that there is no significant difference in the average attendance rates based on parental involvement levels, with a p-value greater than 0.05. This indicates that parental involvement does not have a significant impact on attendance rates.

Attendance Rates by Access to Resources

Next, we explore the attendance rates based on access to resources.

# Summary statistics for attendance rates by access to resources
summary(student_data$Attendance[student_data$Access_to_Resources == "High"])
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  60.00   70.00   79.00   79.87   90.00  100.00 
summary(student_data$Attendance[student_data$Access_to_Resources == "Medium"])
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
     60      70      80      80      90     100 
summary(student_data$Attendance[student_data$Access_to_Resources == "Low"])
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  60.00   71.00   80.00   80.29   91.00  100.00 

The summary statistics of the attendance rates based on access to resources show no significant differences. We will now use ANOVA to test for differences in attendance rates based on access to resources. But first, we need to check the assumptions of ANOVA.

# Sample the data
high_access_to_resources_attendance <- student_data$Attendance[student_data$Access_to_Resources == "High"][sample(sum(student_data$Access_to_Resources == "High"), 100)]
medium_access_to_resources_attendance <- student_data$Attendance[student_data$Access_to_Resources == "Medium"][sample(sum(student_data$Access_to_Resources == "Medium"), 100)]
low_access_to_resources_attendance <- student_data$Attendance[student_data$Access_to_Resources == "Low"][sample(sum(student_data$Access_to_Resources == "Low"), 100)]

# Histogram of attendance rates by access to resources
par(mfrow = c(1, 3))
hist(high_access_to_resources_attendance, main = "High Access to Resources", xlab = "Attendance Rate", col = "skyblue", border = "black")
hist(medium_access_to_resources_attendance, main = "Medium Access to Resources", xlab = "Attendance Rate", col = "skyblue", border = "black")
hist(low_access_to_resources_attendance, main = "Low Access to Resources", xlab = "Attendance Rate", col = "skyblue", border = "black")

# Check assumptions of ANOVA
shapiro.test(high_access_to_resources_attendance)

    Shapiro-Wilk normality test

data:  high_access_to_resources_attendance
W = 0.95112, p-value = 0.0009836
shapiro.test(medium_access_to_resources_attendance)

    Shapiro-Wilk normality test

data:  medium_access_to_resources_attendance
W = 0.94251, p-value = 0.0002752
shapiro.test(low_access_to_resources_attendance)

    Shapiro-Wilk normality test

data:  low_access_to_resources_attendance
W = 0.93998, p-value = 0.0001923

All three histograms and the Shapiro-Wilk test show that the distribution of attendance rates is not normal for all students. We will now use Kruksal-Wallis test to test for differences in attendance rates based on access to resources.

# Kruksal-Wallis test
kruskal.test(Attendance ~ Access_to_Resources, data = student_data)

    Kruskal-Wallis rank sum test

data:  Attendance by Access_to_Resources
Kruskal-Wallis chi-squared = 1.0494, df = 2, p-value = 0.5917

The Kruskal-Wallis test shows that there is no significant difference in the average attendance rates based on access to resources, with a p-value greater than 0.05. This indicates that access to resources does not have a significant impact on attendance rates.

Attendance Rates by Extracurricular Activities

Next, we explore the attendance rates based on participation in extracurricular activities.

# Summary statistics for attendance rates by extracurricular activities
summary(student_data$Attendance[student_data$Extracurricular_Activities == "Yes"])
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
     60      70      80      80      90     100 
summary(student_data$Attendance[student_data$Extracurricular_Activities == "No"])
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  60.00   70.00   80.00   80.05   90.00  100.00 

The summary statistics of the attendance rates based on participation in extracurricular activities show no significant differences. We will now use ANOVA to test for differences in attendance rates based on participation in extracurricular activities. But first, we need to check the assumptions of ANOVA.

# Sample the data
participate_extracurricular_attendance <- student_data$Attendance[student_data$Extracurricular_Activities == "Yes"][sample(sum(student_data$Extracurricular_Activities == "Yes"), 100)]
do_not_participate_extracurricular_attendance <- student_data$Attendance[student_data$Extracurricular_Activities == "No"][sample(sum(student_data$Extracurricular_Activities == "No"), 100)]

# Histogram of attendance rates by extracurricular activities
par(mfrow = c(1, 2))
hist(participate_extracurricular_attendance, main = "Extracurricular Activities", xlab = "Attendance Rate", col = "skyblue", border = "black")
hist(do_not_participate_extracurricular_attendance, main = "No Extracurricular Activities", xlab = "Attendance Rate", col = "skyblue", border = "black")

# Check assumptions of ANOVA
shapiro.test(participate_extracurricular_attendance)

    Shapiro-Wilk normality test

data:  participate_extracurricular_attendance
W = 0.96044, p-value = 0.004321
shapiro.test(do_not_participate_extracurricular_attendance)

    Shapiro-Wilk normality test

data:  do_not_participate_extracurricular_attendance
W = 0.93609, p-value = 0.0001122

Both histograms and the Shapiro-Wilk test show that the distribution of attendance rates is not normal for all students. We will now use Kruksal-Wallis test to test for differences in attendance rates based on participation in extracurricular activities.

# Kruksal-Wallis test
kruskal.test(Attendance ~ Extracurricular_Activities, data = student_data)

    Kruskal-Wallis rank sum test

data:  Attendance by Extracurricular_Activities
Kruskal-Wallis chi-squared = 0.026414, df = 1, p-value = 0.8709

The Kruskal-Wallis test shows that there is no significant difference in the average attendance rates based on participation in extracurricular activities, with a p-value greater than 0.05. This indicates that participation in extracurricular activities does not have a significant impact on attendance rates.

LS0tDQp0aXRsZTogIkdlbmVyYWwgVHJlbmRzIGFuZCBEZXNjcmlwdGl2ZSBBbmFseXNpcyINCmF1dGhvcjogIiZjb3B5OyBIZWN0b3IgTWF0aG9uc2kiDQpkYXRlOiAyMDI0LTEwLTE5DQpvdXRwdXQ6DQogICAgaHRtbF9ub3RlYm9vazoNCiAgICAgICAgdGhlbWU6IGZsYXRseQ0KICAgICAgICBoaWdobGlnaHQ6IHRhbmdvDQogICAgICAgIHRvYzogdHJ1ZQ0KICAgICAgICB0b2NfZmxvYXQ6IHRydWUNCi0tLQ0KDQotLS0tLQ0KDQojIEFic3RyYWN0DQoNClRoaXMgcmVwb3J0IGV4cGxvcmVzIHRoZSByZWxhdGlvbnNoaXBzIGJldHdlZW4gdmFyaW91cyBmYWN0b3JzIGluZmx1ZW5jaW5nIHN0dWRlbnQgcGVyZm9ybWFuY2UsIHVzaW5nIGV4cGxvcmF0b3J5IGRhdGEgYW5hbHlzaXMgKEVEQSkgdG8gaWRlbnRpZnkga2V5IHRyZW5kcyBhbmQgY29ycmVsYXRpb25zLiBUaGUgYW5hbHlzaXMgZm9jdXNlcyBvbiB2YXJpYWJsZXMgc3VjaCBhcyBzdHVkeSBoYWJpdHMsIGFjY2VzcyB0byByZXNvdXJjZXMsIHBhcmVudGFsIGludm9sdmVtZW50LCBhbmQgZW52aXJvbm1lbnRhbCBmYWN0b3JzLCBhbmQgaG93IHRoZXkgaW1wYWN0IGZpbmFsIGV4YW0gc2NvcmVzLiBJbnNpZ2h0cyBnYWluZWQgZnJvbSB0aGUgZGF0YSB3aWxsIGluZm9ybSByZWNvbW1lbmRhdGlvbnMgYWltZWQgYXQgaW1wcm92aW5nIGFjYWRlbWljIG91dGNvbWVzIGZvciBzdHVkZW50cy4NCg0KIyBEYXRhIFNvdXJjZQ0KDQpUaGUgZGF0YXNldCB3YXMgc291cmNlZCBmcm9tIEthZ2dsZSB1bmRlciB0aGUgQ0MwIDEuMCB1bml2ZXJzYWwgIk5vIENvcHlyaWdodCIgbGljZW5zZS4gV2UgYXJlIGZyZWUgdG8gY29weSwgbW9kaWZ5LCBkaXN0cmlidXRlIGFuZCBwZXJmb3JtIHRoZSB3b3JrLCBldmVuIGZvciBjb21tZXJjaWFsIHB1cnBvc2VzLCBhbGwgd2l0aG91dCBhc2tpbmcgcGVybWlzc2lvbi4gTGVhcm4gbW9yZSBhYm91dCB0aGlzIGxpY2Vuc2UgaGVyZSBbaGVyZV0oaHR0cHM6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL3B1YmxpY2RvbWFpbi96ZXJvLzEuMC8pLg0KDQpVUkwgZm9yIGRhdGEgaW4gS2FnZ2xlOiBbU3R1ZGVudCBQZXJmb3JtYW5jZSBGYWN0b3JzIERhdGFzZXRdKGh0dHBzOi8vd3d3LmthZ2dsZS5jb20vZGF0YXNldHMvbGFpbmd1eW4xMjMvc3R1ZGVudC1wZXJmb3JtYW5jZS1mYWN0b3JzKQ0KDQojIEltcG9ydCBhbmQgVmlldyBEYXRhDQoNCmBgYHtyfQ0Kc3R1ZGVudF9kYXRhIDwtIHJlYWQuY3N2KCcuLi9kYXRhL1N0dWRlbnRQZXJmb3JtYW5jZUZhY3RvcnMuY3N2JywgaGVhZGVyID0gVFJVRSkNCnN0dWRlbnRfZGF0YSAgICAjIERpc3BsYXkgdGhlIGRhdGFzZXQNCmBgYA0KDQojIyMgU3VtbWFyeSBTdGF0aXN0aWNzDQoNCmBgYHtyfQ0KIyBTdW1tYXJ5IHN0YXRpc3RpY3MgZm9yIGFsbCB2YXJpYWJsZXMNCnN1bW1hcnkoc3R1ZGVudF9kYXRhKSAgICMgU3VtbWFyeSBzdGF0aXN0aWNzIGZvciBhbGwgdmFyaWFibGVzDQpoZWFkKHN0dWRlbnRfZGF0YSkgICAgICAjIERpc3BsYXkgdGhlIGZpcnN0IGZldyByb3dzIG9mIHRoZSBkYXRhc2V0DQpzdHIoc3R1ZGVudF9kYXRhKSAgICAgICAjIFN0cnVjdHVyZSBvZiB0aGUgZGF0YXNldA0Kc3VtKGlzLm5hKHN0dWRlbnRfZGF0YSkpICAgICMgQ2hlY2sgZm9yIG1pc3NpbmcgdmFsdWVzDQpgYGANCg0KIyMjIERhdGEgQ2xlYW5pbmcNCg0KV2Ugbm93IGNoZWNrIHdoZXRoZXIgdGhlIGRhdGFzZXQgY29udGFpbnMgYW55IG1pc3NpbmcgdmFsdWVzIGFuZCByZW1vdmUgdGhlbSBpZiBuZWNlc3NhcnkuDQoNCmBgYHtyfQ0KIyBDaGVjayBtaXNzaW5nIHZhbHVlcyBpbiBlYWNoIGNvbHVtbg0KY29sU3Vtcyhpcy5uYShzdHVkZW50X2RhdGEpKQ0KYGBgDQoNCldlIGNhbiBzZWUgdGhhdCB0aGVyZSBhcmUgbm8gbWlzc2luZyB2YWx1ZXMgaW4gdGhlIGRhdGFzZXQuDQoNCldlIG5vdyBjaGVjayB0aGUgdW5pcXVlIHZhbHVlcyBpbiBlYWNoIGNhdGVnb3JpY2FsIGNvbHVtbiB0byBpZGVudGlmeSBhbnkgaW5jb25zaXN0ZW5jaWVzLg0KDQpgYGB7cn0NCiMgVW5pcXVlIHZhbHVlcyBpbiBlYWNoIGNhdGVnb3JpY2FsIGNvbHVtbg0KbGFwcGx5KHN0dWRlbnRfZGF0YVssIHNhcHBseShzdHVkZW50X2RhdGEsIGlzLmNoYXJhY3RlcildLCB1bmlxdWUpDQpgYGANCg0KRnJvbSB0aGUgcmVzdWx0cyBhYm92ZSB3ZSBjYW4gVGVhY2hlcl9RdWFsaXR5LCBQYXJlbnRhbF9FZHVjYXRpb25fTGV2ZWwgYW5kIERpc3RhbmNlX2Zyb21fSG9tZSBoYXZlIG1pc3NpbmcgdmFsdWVzLiBXZSB3aWxsIG5vdyBpbnZlc3RpZ2F0ZSBmdXJ0aGVyIHRvIHNlZSBleGFjdGx5IHdoYXQgdGhlc2UgbWlzc2luZyB2YWx1ZXMgYXJlLg0KDQpgYGB7cn0NCiMgQ2hlY2sgZm9yIG1pc3NpbmcgdmFsdWVzIGluIFRlYWNoZXJfUXVhbGl0eQ0KdGVhY2hlcl9xdWFsaXR5X21pc3NpbmcgPC0gc3R1ZGVudF9kYXRhW3N0dWRlbnRfZGF0YSRUZWFjaGVyX1F1YWxpdHkgPT0gIiIsXQ0KdGVhY2hlcl9xdWFsaXR5X21pc3NpbmcNCm5yb3codGVhY2hlcl9xdWFsaXR5X21pc3NpbmcpDQpgYGANCg0KV2UgY2FuIHNlZSB0aGF0IG9ubHkgNzggcm93cyBoYXZlIG1pc3NpbmcgdmFsdWVzIGluIHRoZSBUZWFjaGVyX1F1YWxpdHkgY29sdW1uLiBXZSB3aWxsIG5vdyBpbnZlc3RpZ2F0ZSB0aGUgUGFyZW50YWxfRWR1Y2F0aW9uX0xldmVsIGNvbHVtbi4NCg0KYGBge3J9DQojIENoZWNrIGZvciBtaXNzaW5nIHZhbHVlcyBpbiBQYXJlbnRhbF9FZHVjYXRpb25fTGV2ZWwNCnBhcmVudGFsX2VkdWNhdGlvbl9sZXZlbF9taXNzaW5nIDwtIHN0dWRlbnRfZGF0YVtzdHVkZW50X2RhdGEkUGFyZW50YWxfRWR1Y2F0aW9uX0xldmVsID09ICIiLF0NCnBhcmVudGFsX2VkdWNhdGlvbl9sZXZlbF9taXNzaW5nDQpucm93KHBhcmVudGFsX2VkdWNhdGlvbl9sZXZlbF9taXNzaW5nKQ0KYGBgDQoNCldlIGNhbiBzZWUgdGhhdCA5MCByb3dzIGhhdmUgbWlzc2luZyB2YWx1ZXMgaW4gdGhlIFBhcmVudGFsX0VkdWNhdGlvbl9MZXZlbCBjb2x1bW4uIFdlIHdpbGwgbm93IGludmVzdGlnYXRlIHRoZSBEaXN0YW5jZV9mcm9tX0hvbWUgY29sdW1uLg0KDQpgYGB7cn0NCiMgQ2hlY2sgZm9yIG1pc3NpbmcgdmFsdWVzIGluIERpc3RhbmNlX2Zyb21fSG9tZQ0KZGlzdGFuY2VfZnJvbV9ob21lX21pc3NpbmcgPC0gc3R1ZGVudF9kYXRhW3N0dWRlbnRfZGF0YSREaXN0YW5jZV9mcm9tX0hvbWUgPT0gIiIsXQ0KZGlzdGFuY2VfZnJvbV9ob21lX21pc3NpbmcNCm5yb3coZGlzdGFuY2VfZnJvbV9ob21lX21pc3NpbmcpDQpgYGANCg0KV2UgY2FuIHNlZSB0aGF0IDY3IHJvd3MgaGF2ZSBtaXNzaW5nIHZhbHVlcyBpbiB0aGUgRGlzdGFuY2VfZnJvbV9Ib21lIGNvbHVtbi4gQWxsIHRoZSBtaXNzaW5nIHZhbHVlcyBjb21iaW5lZCBtYWtlIHVwIGxlc3MgdGhhbiAxMCUgb2YgdGhlIGRhdGFzZXQuIFdlIHdpbGwgcmVtb3ZlIHRoZXNlIHJvd3MgZnJvbSB0aGUgZGF0YXNldC4NCg0KYGBge3J9DQojIFJlbW92ZSByb3dzIHdpdGggbWlzc2luZyB2YWx1ZXMNCnN0dWRlbnRfZGF0YSA8LSBzdWJzZXQoc3R1ZGVudF9kYXRhLCBUZWFjaGVyX1F1YWxpdHkgIT0gIiIgJiBQYXJlbnRhbF9FZHVjYXRpb25fTGV2ZWwgIT0gIiIgJiBEaXN0YW5jZV9mcm9tX0hvbWUgIT0gIiIpDQoNCiMgQ2hlY2sgZm9yIG1pc3NpbmcgdmFsdWVzDQpsYXBwbHkoc3R1ZGVudF9kYXRhWywgc2FwcGx5KHN0dWRlbnRfZGF0YSwgaXMuY2hhcmFjdGVyKV0sIHVuaXF1ZSkNCmBgYA0KDQpXZSBub3cgaW52ZXN0aWdhdGUgdGhlIGRlcGVuZGVudCB2YXJpYWJsZSwgRmluYWxfRXhhbV9TY29yZSwgdG8gaWRlbnRpZnkgYW55IG91dGxpZXJzLg0KDQpgYGB7cn0NCiMgT3V0bGllcnMgaW4gRmluYWxfRXhhbV9TY29yZQ0Kb3V0bGllcnNfaW5fZXhhbV9zY29yZSA8LSBzdHVkZW50X2RhdGFbc3R1ZGVudF9kYXRhJEV4YW1fU2NvcmUgPiAxMDAsXQ0Kb3V0bGllcnNfaW5fZXhhbV9zY29yZQ0KbnJvdyhvdXRsaWVyc19pbl9leGFtX3Njb3JlKQ0KYGBgDQoNCldlIGNhbiBzZWUgdGhhdCBvbmx5IDEgc3R1ZGVudCBnb3QgZXhhbSBzY29yZSBvZiAxMDEgd2hpY2ggaXMgYW4gb3V0bGllci4gV2Ugd2lsbCByZW1vdmUgdGhpcyByb3cgZnJvbSB0aGUgZGF0YXNldC4NCg0KYGBge3J9DQojIFJlbW92ZSBvdXRsaWVycw0Kc3R1ZGVudF9kYXRhIDwtIHN1YnNldChzdHVkZW50X2RhdGEsIEV4YW1fU2NvcmUgPD0gMTAwKQ0KYGBgDQoNCk5vdyB0aGF0IHRoZSBkYXRhIGhhcyBiZWVuIGNsZWFuZWQsIHdlIGNhbiBwcm9jZWVkIHdpdGggdGhlIGV4cGxvcmF0b3J5IGRhdGEgYW5hbHlzaXMuDQoNCg0KIyBEaXN0cmlidXRpb24gb2YgRmluYWwgRXhhbSBTY29yZXMNCg0KIyMgRGlzdHJpYnV0aW9uIG9mIEZpbmFsIEV4YW0gU2NvcmVzIChXaXRob3V0IENvbnNpZGVyaW5nIE90aGVyIEZhY3RvcnMpDQpIZXJlIHdlIHdpbGwgZXhwbG9yZSB0aGUgZGlzdHJpYnV0aW9uIG9mIGZpbmFsIGV4YW0gc2NvcmVzIGFtb25nIHN0dWRlbnRzIHdpdGggd2l0aG91dCBjb25zaWRlcmluZyBvdGhlciBmYWN0b3JzLg0KVG8gZmluZCBvdXIgdGhlIGRpc3RyaWJ1dGlvbiBvZiBmaW5hbCBleGFtIHNjb3Jlcywgd2UgZmlyc3QgbmVlZCB0byBzYW1wbGUgdGhlIGRhdGEgYW5kIHBsb3QgYSBoaXN0b2dyYW0uDQpgYGB7cn0NCiMgU2FtcGxlIHRoZSBkYXRhDQpzZXQuc2VlZCgxMjMpDQpleGFtX3Njb3JlX3NhbXBsZSA8LSBzdHVkZW50X2RhdGEkRXhhbV9TY29yZVtzYW1wbGUobnJvdyhzdHVkZW50X2RhdGEpLCAxMDApXQ0KZXhhbV9zY29yZV9zYW1wbGUNCg0KIyBQbG90IGhpc3RvZ3JhbQ0KaGlzdChleGFtX3Njb3JlX3NhbXBsZSwgbWFpbiA9ICJEaXN0cmlidXRpb24gb2YgRmluYWwgRXhhbSBTY29yZXMiLCB4bGFiID0gIkZpbmFsIEV4YW0gU2NvcmUiLCBjb2wgPSAic2t5Ymx1ZSIsIGJvcmRlciA9ICJibGFjayIpDQpgYGANCg0KRnJvbSB0aGUgaGlzdG9ncmFtLCB3ZSBjYW4gc2VlIHRoYXQgdGhlIGRpc3RyaWJ1dGlvbiBvZiBmaW5hbCBleGFtIHNjb3JlcyBpcyBhcHByb3hpbWF0ZWx5IG5vcm1hbC4gV2Ugbm93IHBsb3QgYSBib3hwbG90IHRvIHZpc3VhbGl6ZSB0aGUgc3ByZWFkIG9mIHNjb3JlcyBhbmQgaWRlbnRpZnkgYW55IG91dGxpZXJzLg0KYGBge3J9DQojIEJveHBsb3Qgb2YgZmluYWwgZXhhbSBzY29yZXMNCmJveHBsb3QoZXhhbV9zY29yZV9zYW1wbGUsIG1haW4gPSAiQm94cGxvdCBvZiBGaW5hbCBFeGFtIFNjb3JlcyIsIGNvbCA9ICJza3libHVlIiwgYm9yZGVyID0gImJsYWNrIikNCmBgYA0KDQpUaGUgYm94cGxvdCBzaG93cyB0aGF0IHRoZSBkaXN0cmlidXRpb24gb2YgZmluYWwgZXhhbSBzY29yZXMgaXMgY2VudGVyZWQgYXJvdW5kIHRoZSBtZWRpYW4sIHdpdGggYSBmZXcgb3V0bGllcnMgb24gdGhlIGxvd2VyIGVuZCBvZiB0aGUgc2NhbGUuIE5vdyB3ZSB1c2UgbnVtZXJpY2FsIG1ldGhvZHMgdG8gY29uZmlybSB0aGUgbm9ybWFsaXR5IG9mIHRoZSBkaXN0cmlidXRpb24uDQpgYGB7cn0NCiMgU2hhcGlyby1XaWxrIHRlc3QgZm9yIG5vcm1hbGl0eQ0Kc2hhcGlyby50ZXN0KGV4YW1fc2NvcmVfc2FtcGxlKQ0KYGBgDQoNClRoZSBTaGFwaXJvLVdpbGsgdGVzdCBjb25maXJtcyB0aGF0IHRoZSBkaXN0cmlidXRpb24gb2YgZmluYWwgZXhhbSBzY29yZXMgaXMgbm90IG5vcm1hbCwgd2l0aCBhIHAtdmFsdWUgbGVzcyB0aGFuIDAuMDUuDQoNCiMjIERpc3RyaWJ1dGlvbiBvZiBGaW5hbCBFeGFtIFNjb3JlcyAoUGFyZW50YWxfSW52b2x2ZW1lbnQgQ2F0ZWdvcnkpDQoNCk5leHQsIHdlIGV4cGxvcmUgdGhlIGRpc3RyaWJ1dGlvbiBvZiBmaW5hbCBleGFtIHNjb3JlcyBiYXNlZCBvbiBwYXJlbnRhbCBpbnZvbHZlbWVudCBsZXZlbHMuIFdlIHdpbGwgY3JlYXRlIGEgYm94cGxvdCB0byBjb21wYXJlIHRoZSBzY29yZXMgb2Ygc3R1ZGVudHMgd2l0aCBkaWZmZXJlbnQgbGV2ZWxzIG9mIHBhcmVudGFsIGludm9sdmVtZW50Lg0KYGBge3J9DQojIFNhbXBsZSB0aGUgZGF0YQ0KaGlnaF9wYXJlbnRhbF9pbnZvbHZlbWVudCA8LSBzdHVkZW50X2RhdGEkRXhhbV9TY29yZVtzdHVkZW50X2RhdGEkUGFyZW50YWxfSW52b2x2ZW1lbnQgPT0gIkhpZ2giXVtzYW1wbGUoc3VtKHN0dWRlbnRfZGF0YSRQYXJlbnRhbF9JbnZvbHZlbWVudCA9PSAiSGlnaCIpLCAxMDApXQ0KbWVkaXVtX3BhcmVudGFsX2ludm9sdmVtZW50IDwtIHN0dWRlbnRfZGF0YSRFeGFtX1Njb3JlW3N0dWRlbnRfZGF0YSRQYXJlbnRhbF9JbnZvbHZlbWVudCA9PSAiTWVkaXVtIl1bc2FtcGxlKHN1bShzdHVkZW50X2RhdGEkUGFyZW50YWxfSW52b2x2ZW1lbnQgPT0gIk1lZGl1bSIpLCAxMDApXQ0KbG93X3BhcmVudGFsX2ludm9sdmVtZW50IDwtIHN0dWRlbnRfZGF0YSRFeGFtX1Njb3JlW3N0dWRlbnRfZGF0YSRQYXJlbnRhbF9JbnZvbHZlbWVudCA9PSAiTG93Il1bc2FtcGxlKHN1bShzdHVkZW50X2RhdGEkUGFyZW50YWxfSW52b2x2ZW1lbnQgPT0gIkxvdyIpLCAxMDApXQ0KDQojIEhpc3RvZ3JhbSBvZiBmaW5hbCBleGFtIHNjb3JlcyBieSBwYXJlbnRhbCBpbnZvbHZlbWVudA0KcGFyKG1mcm93ID0gYygxLCAzKSkNCmhpc3QoaGlnaF9wYXJlbnRhbF9pbnZvbHZlbWVudCwgbWFpbiA9ICJIaWdoIFBhcmVudGFsIEludm9sdmVtZW50IiwgeGxhYiA9ICJGaW5hbCBFeGFtIFNjb3JlIiwgY29sID0gInNreWJsdWUiLCBib3JkZXIgPSAiYmxhY2siKQ0KaGlzdChtZWRpdW1fcGFyZW50YWxfaW52b2x2ZW1lbnQsIG1haW4gPSAiTWVkaXVtIFBhcmVudGFsIEludm9sdmVtZW50IiwgeGxhYiA9ICJGaW5hbCBFeGFtIFNjb3JlIiwgY29sID0gInNreWJsdWUiLCBib3JkZXIgPSAiYmxhY2siKQ0KaGlzdChsb3dfcGFyZW50YWxfaW52b2x2ZW1lbnQsIG1haW4gPSAiTG93IFBhcmVudGFsIEludm9sdmVtZW50IiwgeGxhYiA9ICJGaW5hbCBFeGFtIFNjb3JlIiwgY29sID0gInNreWJsdWUiLCBib3JkZXIgPSAiYmxhY2siKQ0KYGBgDQoNClRoZSB0aHJlZSBoaXN0b2dyYW1zIHNob3cgdGhlIGRpc3RyaWJ1dGlvbiBvZiBmaW5hbCBleGFtIHNjb3JlcyBmb3Igc3R1ZGVudHMgd2l0aCBoaWdoLCBtZWRpdW0sIGFuZCBsb3cgbGV2ZWxzIG9mIHBhcmVudGFsIGludm9sdmVtZW50LiBXZSBjYW4gc2VlIHRoYXQgdGhlIGRpc3RyaWJ1dGlvbiBvZiB0aGUgc2NvcmVzIHNlZW1zIHRvIGJlIHNpbWlsYXIgYWNyb3NzIGFsbCB0aHJlZSBjYXRlZ29yaWVzLiBUaGV5IHNlZW0gdG8gZm9sbG93IGEgbm9ybWFsIGRpc3RyaWJ1dGlvbiwgd2l0aCBhIHNsaWdodCBza2V3IHRvd2FyZHMgaGlnaGVyIHNjb3JlcyBmb3Igc3R1ZGVudHMgd2l0aCBoaWdoIHBhcmVudGFsIGludm9sdmVtZW50Lg0KV2Ugbm93IHVzZSBudW1lcmljYWwgbWV0aG9kcyB0byBjb25maXJtIHRoZSBub3JtYWxpdHkgb2YgdGhlIGRpc3RyaWJ1dGlvbnMuDQpgYGB7cn0NCiMgU2hhcGlyby1XaWxrIHRlc3QgZm9yIG5vcm1hbGl0eQ0Kc2hhcGlyby50ZXN0KGhpZ2hfcGFyZW50YWxfaW52b2x2ZW1lbnQpDQpzaGFwaXJvLnRlc3QobWVkaXVtX3BhcmVudGFsX2ludm9sdmVtZW50KQ0Kc2hhcGlyby50ZXN0KGxvd19wYXJlbnRhbF9pbnZvbHZlbWVudCkNCmBgYA0KDQpUaGUgU2hhcGlyby1XaWxrIHRlc3QgY29uZmlybXMgdGhhdCB0aGUgZGlzdHJpYnV0aW9ucyBvZiBmaW5hbCBleGFtIHNjb3JlcyBmb3IgYWxsIHN0dWRlbnRzIHdpdGggb2YgcGFyZW50YWwgaW52b2x2ZW1lbnQgYXJlIGFwcHJveGltYXRlbHkgbm9ybWFsLCB3aXRoIHAtdmFsdWVzIGdyZWF0ZXIgdGhhbiAwLjA1Lg0KDQojIyBEaXN0cmlidXRpb24gb2YgRmluYWwgRXhhbSBTY29yZXMgKEFjY2Vzc190b19SZXNvdXJjZXMgQ2F0ZWdvcnkpDQoNCk5leHQsIHdlIGV4cGxvcmUgdGhlIGRpc3RyaWJ1dGlvbiBvZiBmaW5hbCBleGFtIHNjb3JlcyBiYXNlZCBvbiBhY2Nlc3MgdG8gcmVzb3VyY2VzLiBXZSB3aWxsIGNyZWF0ZSBhIGJveHBsb3QgdG8gY29tcGFyZSB0aGUgc2NvcmVzIG9mIHN0dWRlbnRzIHdpdGggZGlmZmVyZW50IGxldmVscyBvZiBhY2Nlc3MgdG8gcmVzb3VyY2VzLg0KYGBge3J9DQojIFNhbXBsZSB0aGUgZGF0YQ0KaGlnaF9hY2Nlc3NfdG9fcmVzb3VyY2VzIDwtIHN0dWRlbnRfZGF0YSRFeGFtX1Njb3JlW3N0dWRlbnRfZGF0YSRBY2Nlc3NfdG9fUmVzb3VyY2VzID09ICJIaWdoIl1bc2FtcGxlKHN1bShzdHVkZW50X2RhdGEkQWNjZXNzX3RvX1Jlc291cmNlcyA9PSAiSGlnaCIpLCAxMDApXQ0KbWVkaXVtX2FjY2Vzc190b19yZXNvdXJjZXMgPC0gc3R1ZGVudF9kYXRhJEV4YW1fU2NvcmVbc3R1ZGVudF9kYXRhJEFjY2Vzc190b19SZXNvdXJjZXMgPT0gIk1lZGl1bSJdW3NhbXBsZShzdW0oc3R1ZGVudF9kYXRhJEFjY2Vzc190b19SZXNvdXJjZXMgPT0gIk1lZGl1bSIpLCAxMDApXQ0KbG93X2FjY2Vzc190b19yZXNvdXJjZXMgPC0gc3R1ZGVudF9kYXRhJEV4YW1fU2NvcmVbc3R1ZGVudF9kYXRhJEFjY2Vzc190b19SZXNvdXJjZXMgPT0gIkxvdyJdW3NhbXBsZShzdW0oc3R1ZGVudF9kYXRhJEFjY2Vzc190b19SZXNvdXJjZXMgPT0gIkxvdyIpLCAxMDApXQ0KDQojIEhpc3RvZ3JhbSBvZiBmaW5hbCBleGFtIHNjb3JlcyBieSBhY2Nlc3MgdG8gcmVzb3VyY2VzDQpwYXIobWZyb3cgPSBjKDEsIDMpKQ0KaGlzdChoaWdoX2FjY2Vzc190b19yZXNvdXJjZXMsIG1haW4gPSAiSGlnaCBBY2Nlc3MgdG8gUmVzb3VyY2VzIiwgeGxhYiA9ICJGaW5hbCBFeGFtIFNjb3JlIiwgY29sID0gInNreWJsdWUiLCBib3JkZXIgPSAiYmxhY2siKQ0KaGlzdChtZWRpdW1fYWNjZXNzX3RvX3Jlc291cmNlcywgbWFpbiA9ICJNZWRpdW0gQWNjZXNzIHRvIFJlc291cmNlcyIsIHhsYWIgPSAiRmluYWwgRXhhbSBTY29yZSIsIGNvbCA9ICJza3libHVlIiwgYm9yZGVyID0gImJsYWNrIikNCmhpc3QobG93X2FjY2Vzc190b19yZXNvdXJjZXMsIG1haW4gPSAiTG93IEFjY2VzcyB0byBSZXNvdXJjZXMiLCB4bGFiID0gIkZpbmFsIEV4YW0gU2NvcmUiLCBjb2wgPSAic2t5Ymx1ZSIsIGJvcmRlciA9ICJibGFjayIpDQoNCnBsb3QoZGVuc2l0eShsb3dfYWNjZXNzX3RvX3Jlc291cmNlcyksIG1haW4gPSAiTG93IEFjY2VzcyB0byBSZXNvdXJjZXMiLCB4bGFiID0gIkZpbmFsIEV4YW0gU2NvcmUiLCBjb2wgPSAic2t5Ymx1ZSIpDQpwbG90KGRlbnNpdHkobWVkaXVtX2FjY2Vzc190b19yZXNvdXJjZXMpLCBtYWluID0gIk1lZGl1bSBBY2Nlc3MgdG8gUmVzb3VyY2VzIiwgeGxhYiA9ICJGaW5hbCBFeGFtIFNjb3JlIiwgY29sID0gInNreWJsdWUiKQ0KcGxvdChkZW5zaXR5KGhpZ2hfYWNjZXNzX3RvX3Jlc291cmNlcyksIG1haW4gPSAiSGlnaCBBY2Nlc3MgdG8gUmVzb3VyY2VzIiwgeGxhYiA9ICJGaW5hbCBFeGFtIFNjb3JlIiwgY29sID0gInNreWJsdWUiKQ0KYGBgDQoNClRoZSBoaXN0b2dyYW1zIGFuZCBkZW5zaXR5IHBsb3RzIHNob3cgdGhlIGRpc3RyaWJ1dGlvbiBvZiBmaW5hbCBleGFtIHNjb3JlcyBmb3Igc3R1ZGVudHMgd2l0aCBoaWdoLCBtZWRpdW0sIGFuZCBsb3cgbGV2ZWxzIG9mIGFjY2VzcyB0byByZXNvdXJjZXMuIFRoZSBkaXN0cmlidXRpb25zIHNlZW0gdG8gYmUgc2ltaWxhciBhY3Jvc3MgYWxsIHRocmVlIGNhdGVnb3JpZXMsIHdpdGggYSBzbGlnaHQgc2tldyB0b3dhcmRzIGhpZ2hlciBzY29yZXMgZm9yIHN0dWRlbnRzIHdpdGggaGlnaCBhY2Nlc3MgdG8gcmVzb3VyY2VzLiBXZSB3aWxsIG5vdyB1c2UgbnVtZXJpY2FsIG1ldGhvZHMgdG8gY29uZmlybSB0aGUgbm9ybWFsaXR5IG9mIHRoZSBkaXN0cmlidXRpb25zLg0KDQpgYGB7cn0NCiMgU2hhcGlyby1XaWxrIHRlc3QgZm9yIG5vcm1hbGl0eQ0Kc2hhcGlyby50ZXN0KGhpZ2hfYWNjZXNzX3RvX3Jlc291cmNlcykNCnNoYXBpcm8udGVzdChtZWRpdW1fYWNjZXNzX3RvX3Jlc291cmNlcykNCnNoYXBpcm8udGVzdChsb3dfYWNjZXNzX3RvX3Jlc291cmNlcykNCmBgYA0KDQpUaGUgU2hhcGlyby1XaWxrIHRlc3QgY29uZmlybXMgdGhhdCB0aGUgZGlzdHJpYnV0aW9ucyBvZiBmaW5hbCBleGFtIHNjb3JlcyBmb3Igc3R1ZGVudHMgd2l0aCBoaWdoIHJlc291cmNlcyBhcmUgYXBwcm94aW1hdGVseSBub3JtYWwsIHdpdGggYSBwLXZhbHVlIGdyZWF0ZXIgdGhhbiAwLjA1LiBIb3dldmVyLCB0aGUgZGlzdHJpYnV0aW9ucyBmb3Igc3R1ZGVudHMgd2l0aCBtZWRpdW0gYW5kIGxvdyByZXNvdXJjZXMgYXJlIHNsaWdodGx5IHNrZXdlZCwgd2l0aCBwLXZhbHVlcyBsZXNzIHRoYW4gMC4wNS4gVGhpcyBjb25jbHVkZSB0aGF0IHRoZSBkaXN0cmlidXRpb24gb2YgZmluYWwgZXhhbSBzY29yZXMgZm9yIHN0dWRlbnRzIHdpdGggaGlnaCByZXNvdXJjZXMgaXMgbm9ybWFsLCB3aGlsZSB0aGUgZGlzdHJpYnV0aW9ucyBmb3Igc3R1ZGVudHMgd2l0aCBtZWRpdW0gYW5kIGxvdyByZXNvdXJjZXMgYXJlIHNsaWdodGx5IHNrZXdlZC4NCg0KIyMgRGlzdHJpYnV0aW9uIG9mIEZpbmFsIEV4YW0gU2NvcmVzIChFeHRyYWN1cnJpY3VsYXJfQWN0aXZpdGllcyBDYXRlZ29yeSkNCg0KTmV4dCwgd2UgZXhwbG9yZSB0aGUgZGlzdHJpYnV0aW9uIG9mIGZpbmFsIGV4YW0gc2NvcmVzIGJhc2VkIG9uIHBhcnRpY2lwYXRpb24gaW4gZXh0cmFjdXJyaWN1bGFyIGFjdGl2aXRpZXMuIFdlIHdpbGwgY3JlYXRlIGEgYm94cGxvdCB0byBjb21wYXJlIHRoZSBzY29yZXMgb2Ygc3R1ZGVudHMgd2hvIHBhcnRpY2lwYXRlIGluIGV4dHJhY3VycmljdWxhciBhY3Rpdml0aWVzIGFuZCB0aG9zZSB3aG8gZG8gbm90Lg0KYGBge3J9DQojIFNhbXBsZSB0aGUgZGF0YQ0KcGFydGljaXBhdGVfZXh0cmFjdXJyaWN1bGFyIDwtIHN0dWRlbnRfZGF0YSRFeGFtX1Njb3JlW3N0dWRlbnRfZGF0YSRFeHRyYWN1cnJpY3VsYXJfQWN0aXZpdGllcyA9PSAiWWVzIl1bc2FtcGxlKHN1bShzdHVkZW50X2RhdGEkRXh0cmFjdXJyaWN1bGFyX0FjdGl2aXRpZXMgPT0gIlllcyIpLCAxMDApXQ0KZG9fbm90X3BhcnRpY2lwYXRlX2V4dHJhY3VycmljdWxhciA8LSBzdHVkZW50X2RhdGEkRXhhbV9TY29yZVtzdHVkZW50X2RhdGEkRXh0cmFjdXJyaWN1bGFyX0FjdGl2aXRpZXMgPT0gIk5vIl1bc2FtcGxlKHN1bShzdHVkZW50X2RhdGEkRXh0cmFjdXJyaWN1bGFyX0FjdGl2aXRpZXMgPT0gIk5vIiksIDEwMCldDQoNCiMgQm94cGxvdCBvZiBmaW5hbCBleGFtIHNjb3JlcyBieSBleHRyYWN1cnJpY3VsYXIgYWN0aXZpdGllcw0KYm94cGxvdChzdHVkZW50X2RhdGEkRXhhbV9TY29yZSB+IHN0dWRlbnRfZGF0YSRFeHRyYWN1cnJpY3VsYXJfQWN0aXZpdGllcywgbWFpbiA9ICJGaW5hbCBFeGFtIFNjb3JlcyBieSBFeHRyYWN1cnJpY3VsYXIgQWN0aXZpdGllcyIsIHhsYWIgPSAiRXh0cmFjdXJyaWN1bGFyIEFjdGl2aXRpZXMiLCB5bGFiID0gIkZpbmFsIEV4YW0gU2NvcmUiLCBjb2wgPSAic2t5Ymx1ZSIsIGJvcmRlciA9ICJibGFjayIpDQpgYGANCg0KVGhlIGJveHBsb3Qgc2hvd3MgdGhhdCBzdHVkZW50cyB3aG8gcGFydGljaXBhdGUgaW4gZXh0cmFjdXJyaWN1bGFyIGFjdGl2aXRpZXMgdGVuZCB0byBoYXZlIGhpZ2hlciBmaW5hbCBleGFtIHNjb3JlcyBjb21wYXJlZCB0byB0aG9zZSB3aG8gZG8gbm90LiBOb3cgd2Ugd2lsbCB2aXN1YWxpemUgdGhlIGRpc3RyaWJ1dGlvbiBvZiBzY29yZXMgZm9yIGJvdGggZ3JvdXBzIHVzaW5nIGhpc3RvZ3JhbXMuDQpgYGB7cn0NCiMgSGlzdG9ncmFtIG9mIGZpbmFsIGV4YW0gc2NvcmVzIGJ5IGV4dHJhY3VycmljdWxhciBhY3Rpdml0aWVzDQpwYXIobWZyb3cgPSBjKDEsIDIpKQ0KaGlzdChwYXJ0aWNpcGF0ZV9leHRyYWN1cnJpY3VsYXIsIG1haW4gPSAiRXh0cmFjdXJyaWN1bGFyIEFjdGl2aXRpZXMiLCB4bGFiID0gIkZpbmFsIEV4YW0gU2NvcmUiLCBjb2wgPSAic2t5Ymx1ZSIsIGJvcmRlciA9ICJibGFjayIpDQpoaXN0KGRvX25vdF9wYXJ0aWNpcGF0ZV9leHRyYWN1cnJpY3VsYXIsIG1haW4gPSAiTm8gRXh0cmFjdXJyaWN1bGFyIEFjdGl2aXRpZXMiLCB4bGFiID0gIkZpbmFsIEV4YW0gU2NvcmUiLCBjb2wgPSAic2t5Ymx1ZSIsIGJvcmRlciA9ICJibGFjayIpDQpgYGANCg0KQm90aCBoaXN0b2dyYW1zIHNob3cgbm9ybWFsIGRpc3RyaWJ1dGlvbnMgb2YgZmluYWwgZXhhbSBzY29yZXMgZm9yIHN0dWRlbnRzIHdobyBwYXJ0aWNpcGF0ZSBpbiBleHRyYWN1cnJpY3VsYXIgYWN0aXZpdGllcyBhbmQgdGhvc2Ugd2hvIGRvIG5vdC4gV2Ugd2lsbCBub3cgdXNlIG51bWVyaWNhbCBtZXRob2RzIHRvIGNvbmZpcm0gdGhlIG5vcm1hbGl0eSBvZiB0aGUgZGlzdHJpYnV0aW9ucy4NCg0KYGBge3J9DQojIFNoYXBpcm8tV2lsayB0ZXN0IGZvciBub3JtYWxpdHkNCnNoYXBpcm8udGVzdChwYXJ0aWNpcGF0ZV9leHRyYWN1cnJpY3VsYXIpDQpzaGFwaXJvLnRlc3QoZG9fbm90X3BhcnRpY2lwYXRlX2V4dHJhY3VycmljdWxhcikNCmBgYA0KDQpUaGUgU2hhcGlyby1XaWxrIHRlc3QgY29uZmlybXMgdGhhdCBib3RoIGRpc3RyaWJ1dGlvbnMgb2YgZmluYWwgZXhhbSBzY29yZXMgZm9yIHN0dWRlbnRzIHdobyBwYXJ0aWNpcGF0ZSBpbiBleHRyYWN1cnJpY3VsYXIgYWN0aXZpdGllcyBhbmQgdGhvc2Ugd2hvIGRvIG5vdCBhcmUgYXBwcm94aW1hdGVseSBub3JtYWwsIHdpdGggcC12YWx1ZXMgZ3JlYXRlciB0aGFuIDAuMDUuDQoNCiMjIERpc3RyaWJ1dGlvbiBvZiBGaW5hbCBFeGFtIFNjb3JlcyAoTW90aXZhdGlvbl9MZXZlbCBDYXRlZ29yeSkNCg0KTmV4dCB3ZSBleHBsb3JlIHRoZSBkaXN0cmlidXRpb24gb2YgZmluYWwgZXhhbSBzY29yZXMgYmFzZWQgb24gbW90aXZhdGlvbiBsZXZlbHMuIFdlIHdpbGwgY3JlYXRlIGEgaGlzdG9ncmFtIHRvIGNvbXBhcmUgdGhlIHNjb3JlcyBvZiBzdHVkZW50cyB3aXRoIGRpZmZlcmVudCBtb3RpdmF0aW9uIGxldmVscy4NCmBgYHtyfQ0KIyBTbWFwbGUgRGF0YQ0KaGlnaF9tb3RpdmF0aW9uIDwtIHN0dWRlbnRfZGF0YSRFeGFtX1Njb3JlW3N0dWRlbnRfZGF0YSRNb3RpdmF0aW9uX0xldmVsID09ICJIaWdoIl1bc2FtcGxlKHN1bShzdHVkZW50X2RhdGEkTW90aXZhdGlvbl9MZXZlbCA9PSAiSGlnaCIpLCAxMDApXQ0KbWVkaXVtX21vdGl2YXRpb24gPC0gc3R1ZGVudF9kYXRhJEV4YW1fU2NvcmVbc3R1ZGVudF9kYXRhJE1vdGl2YXRpb25fTGV2ZWwgPT0gIkhpZ2giXVtzYW1wbGUoc3VtKHN0dWRlbnRfZGF0YSRNb3RpdmF0aW9uX0xldmVsID09ICJNZWRpdW0iKSwgMTAwKV0NCmxvd19tb3RpdmF0aW9uIDwtIHN0dWRlbnRfZGF0YSRFeGFtX1Njb3JlW3N0dWRlbnRfZGF0YSRNb3RpdmF0aW9uX0xldmVsID09ICJIaWdoIl1bc2FtcGxlKHN1bShzdHVkZW50X2RhdGEkTW90aXZhdGlvbl9MZXZlbCA9PSAiTG93IiksIDEwMCldDQoNCiMgSGlzdG9ncmFtIG9mIGZpbmFsIGV4YW0gc2NvcmVzIGJ5IG1vdGl2YXRpb24gbGV2ZWwNCnBhcihtZnJvdyA9IGMoMSwgMykpDQpoaXN0KGhpZ2hfbW90aXZhdGlvbiwgbWFpbiA9ICJIaWdoIE1vdGl2YXRpb24gTGV2ZWwiLCB4bGFiID0gIkZpbmFsIEV4YW0gU2NvcmUiLCBjb2wgPSAic2t5Ymx1ZSIsIGJvcmRlciA9ICJibGFjayIpDQpoaXN0KG1lZGl1bV9tb3RpdmF0aW9uLCBtYWluID0gIk1lZGl1bSBNb3RpdmF0aW9uIExldmVsIiwgeGxhYiA9ICJGaW5hbCBFeGFtIFNjb3JlIiwgY29sID0gInNreWJsdWUiLCBib3JkZXIgPSAiYmxhY2siKQ0KaGlzdChsb3dfbW90aXZhdGlvbiwgbWFpbiA9ICJMb3cgTW90aXZhdGlvbiBMZXZlbCIsIHhsYWIgPSAiRmluYWwgRXhhbSBTY29yZSIsIGNvbCA9ICJza3libHVlIiwgYm9yZGVyID0gImJsYWNrIikNCmBgYA0KDQotICoqSGlnaCBNb3RpdmF0aW9uIExldmVsKio6IFRoZSBkaXN0cmlidXRpb24gaXMgZmFpcmx5IGNvbmNlbnRyYXRlZCwgd2l0aCBtb3N0IHNjb3JlcyBjbHVzdGVyZWQgYXJvdW5kIDY1LTc1LiBUaGUgc2NvcmVzIGFyZSB0aWdodGx5IHBhY2tlZCBzaG93aW5nIGEgbmFycm93ZXIgc3ByZWFkLiBBIHNpZ25pZmljYW50IG51bWJlciBvZiBzdHVkZW50cyBzY29yZWQgd2l0aGluIHRoaXMgcmFuZ2UgaW5kaWNhdGluZyBhIG1vcmUgY29uc2lzdGVudCBwZXJmb3JtYW5jZS4NCi0gKipNZWRpdW0gTW90aXZhdGlvbiBMZXZlbCoqOiBUaGUgZGlzdHJpYnV0aW9uIGlzIG1vcmUgc3ByZWFkIG91dCBjb21wYXJlZCB0byB0aGUgIkhpZ2ggTW90aXZhdGlvbiIgZ3JvdXAsIHdpdGggc2NvcmVzIHJvdWdobHkgYmV0d2VlbiA2MiBhbmQgNzQuIFRoaXMgaW5kaWNhdGVzIGEgbW9kZXJhdGUgbGV2ZWwgb2YgdmFyaWFiaWxpdHkgaW4gdGhlIHNjb3Jlcy4gVGhlIGZyZXF1ZW5jeSBvZiBzY29yZXMgaXMgbG93ZXIgaW4gZWFjaCBiaW4gY29tcGFyZWQgdG8gdGhlIGhpZ2ggbW90aXZhdGlvbiBncm91cCwgcG9zc2libHkgcmVmbGVjdGluZyBhIHNtYWxsZXIgZ3JvdXAgc2l6ZSBvciBsZXNzIHVuaWZvcm0gcGVyZm9ybWFuY2UuDQotICoqTG93IE1vdGl2YXRpb24gTGV2ZWwqKjogVGhlIGRpc3RyaWJ1dGlvbiBhcHBlYXJzIHNrZXdlZCB0b3dhcmQgdGhlIGxvd2VyIGVuZCwgd2l0aCBhIG5vdGljZWFibGUgY2x1c3RlciBhcm91bmQgNjDigJM3MC4gVGhlIHNjb3JlcyBoYXZlIGEgd2lkZXIgc3ByZWFkLCBleHRlbmRpbmcgZXZlbiBiZXlvbmQgODUsIHRob3VnaCB3aXRoIGZld2VyIHN0dWRlbnRzIGFjaGlldmluZyB0aG9zZSBoaWdoIHNjb3Jlcy4gTWFueSBzdHVkZW50cyBzY29yZWQgdG93YXJkIHRoZSBsb3dlciBlbmQgb2YgdGhlIGRpc3RyaWJ1dGlvbiwgc3VnZ2VzdGluZyBsZXNzIGVmZmVjdGl2ZSBleGFtIHBlcmZvcm1hbmNlIG92ZXJhbGwuDQoNCkhpZ2hlciBtb3RpdmF0aW9uIGxldmVscyBjb3JyZWxhdGUgd2l0aCBtb3JlIGNvbnNpc3RlbnQgYW5kIGNvbmNlbnRyYXRlZCBleGFtIHNjb3JlcyBhcm91bmQgYSBjZW50cmFsIHJhbmdlLiBMb3dlciBtb3RpdmF0aW9uIGxldmVscyBhcmUgYXNzb2NpYXRlZCB3aXRoIGdyZWF0ZXIgdmFyaWFiaWxpdHkgYW5kIG1vcmUgc2NvcmVzIGNsdXN0ZXJpbmcgaW4gdGhlIGxvd2VyIHJhbmdlLiBNb3RpdmF0aW9uIGxldmVsIHNlZW1zIHRvIGhhdmUgYSBzdHJvbmcgaW5mbHVlbmNlIG9uIGV4YW0gcGVyZm9ybWFuY2UsIHdpdGggaGlnaGVyIG1vdGl2YXRpb24gbGlua2VkIHRvIGJldHRlciBhbmQgbW9yZSB1bmlmb3JtIG91dGNvbWVzLg0KDQpgYGB7cn0NCiMgU2hhcGlyby1XaWxrIHRlc3QgZm9yIG5vcm1hbGl0eQ0Kc2hhcGlyby50ZXN0KGhpZ2hfbW90aXZhdGlvbikNCnNoYXBpcm8udGVzdChtZWRpdW1fbW90aXZhdGlvbikNCnNoYXBpcm8udGVzdChsb3dfbW90aXZhdGlvbikNCmBgYA0KDQpUaGUgU2hhcGlyby1XaWxrIHRlc3QgY29uZmlybXMgdGhhdCB0aGUgZGlzdHJpYnV0aW9ucyBvZiBmaW5hbCBleGFtIHNjb3JlcyBmb3Igc3R1ZGVudHMgd2l0aCBtZWRpdW0gbW90aXZhdGlvbiBsZXZlbHMgYXJlIGFwcHJveGltYXRlbHkgbm9ybWFsLCB3aXRoIHAtdmFsdWUgZ3JlYXRlciB0aGFuIDAuMDUuIEhvd2V2ZXIsIHRoZSBkaXN0cmlidXRpb24gZm9yIHN0dWRlbnRzIHdpdGggaGlnaCBhbmQgbG93IG1vdGl2YXRpb24gbGV2ZWxzIGlzIHNsaWdodGx5IHNrZXdlZCwgd2l0aCBhIHAtdmFsdWUgbGVzcyB0aGFuIDAuMDUuDQoNCiMjIERpc3RyaWJ1dGlvbiBvZiBGaW5hbCBFeGFtIFNjb3JlcyAoSW50ZXJuZXRfQWNjZXNzIENhdGVnb3J5KQ0KDQpOZXh0LCB3ZSBleHBsb3JlIHRoZSBkaXN0cmlidXRpb24gb2YgZmluYWwgZXhhbSBzY29yZXMgYmFzZWQgb24gaW50ZXJuZXQgYWNjZXNzLiBXZSB3aWxsIGNyZWF0ZSBhIGJveHBsb3QgdG8gY29tcGFyZSB0aGUgc2NvcmVzIG9mIHN0dWRlbnRzIHdpdGggYW5kIHdpdGhvdXQgaW50ZXJuZXQgYWNjZXNzLg0KYGBge3J9DQojIFNhbXBsZSB0aGUgZGF0YQ0KaW50ZXJuZXRfYWNjZXNzIDwtIHN0dWRlbnRfZGF0YSRFeGFtX1Njb3JlW3N0dWRlbnRfZGF0YSRJbnRlcm5ldF9BY2Nlc3MgPT0gIlllcyJdW3NhbXBsZShzdW0oc3R1ZGVudF9kYXRhJEludGVybmV0X0FjY2VzcyA9PSAiWWVzIiksIDEwMCldDQpub19pbnRlcm5ldF9hY2Nlc3MgPC0gc3R1ZGVudF9kYXRhJEV4YW1fU2NvcmVbc3R1ZGVudF9kYXRhJEludGVybmV0X0FjY2VzcyA9PSAiTm8iXVtzYW1wbGUoc3VtKHN0dWRlbnRfZGF0YSRJbnRlcm5ldF9BY2Nlc3MgPT0gIk5vIiksIDEwMCldDQoNCiMgSGlzdG9ncmFtIG9mIGZpbmFsIGV4YW0gc2NvcmVzIGJ5IGludGVybmV0IGFjY2Vzcw0KcGFyKG1mcm93ID0gYygxLCAyKSkNCmhpc3QoaW50ZXJuZXRfYWNjZXNzLCBtYWluID0gIkludGVybmV0IEFjY2VzcyIsIHhsYWIgPSAiRmluYWwgRXhhbSBTY29yZSIsIGNvbCA9ICJza3libHVlIiwgYm9yZGVyID0gImJsYWNrIikNCmhpc3Qobm9faW50ZXJuZXRfYWNjZXNzLCBtYWluID0gIk5vIEludGVybmV0IEFjY2VzcyIsIHhsYWIgPSAiRmluYWwgRXhhbSBTY29yZSIsIGNvbCA9ICJza3libHVlIiwgYm9yZGVyID0gImJsYWNrIikNCmBgYA0KDQotICoqSW50ZXJuZXQgQWNjZXNzKio6IFRoZSBkaXN0cmlidXRpb24gYXBwZWFycyBmYWlybHkgc3ltbWV0cmljLCB3aXRoIG1vc3Qgc2NvcmVzIGNsdXN0ZXJlZCBiZXR3ZWVuIDYzIGFuZCA3MC4gVGhlIG1vZGUgb3IgbW9zdCBmcmVxdWVudCBzY29yZSBzZWVtcyB0byBmYWxsIGFyb3VuZCA2NS02OC4gU2NvcmVzIGFyZSBjb25jZW50cmF0ZWQgYmV0d2VlbiA2MCBhbmQgNzAgLCB3aXRoIGZldyBiZWxvdyBvciBhYm92ZSB0aGlzIHJhbmdlLiB0aGUgaGlzdG9ncmFtIHNob3dzIGEgbW9kZXJhdGUgc3ByZWFkIG9mIHNjb3JlcywgaW5kaWNhdGluZyBjb25zaXN0ZW50IHBlcmZvcm1hbmNlIGFtb25nIHN0dWRlbnRzLg0KLSAqKk5vIEludGVybmV0IEFjY2VzcyoqOiBUaGlzIGRpc3RyaWJ1dGlvbiBpcyBzbGlnaHRseSBza2V3ZWQsIHdpdGggc2NvcmVzIHByaW1hcmlseSBjbHVzdGVyZWQgYXJvdW5kIDY1IGFuZCBleHRlbmRpbmcgdG93YXJkIDcwLiBUaGVyZSBhcmUgc29tZSBvdXRsaWVycyBiZXlvbmQgNzUuIFRoZSBoaWdoZXN0IGZyZXF1ZW5jeSBvY2N1cnMgYXJvdW5kIDY1LiBTY29yZXMgYXJlIG1vcmUgd2lkZWx5IGRpc3RyaWJ1dGVkIGNvbXBhcmVkIHRvIHRoZSBfX0ludGVybmV0IEFjY2Vzc19fIGdyb3VwLCB3aXRoIHNvbWUgc3R1ZGVudHMgc2NvcmluZyBhcyBsb3cgYXMgNTUgYW5kIG90aGVycyBleGNlZWRpbmcgODAuIFRoZSBncm91cCBpcyBsYXJnZXIsIGFzIHNlZW4gYnkgdGhlIGhpZ2hlciBmcmVxdWVuY3kgdmFsdWVzIChiYXJzKS4NCg0KYGBge3J9DQojIFNoYXBpcm8tV2lsayB0ZXN0IGZvciBub3JtYWxpdHkNCnNoYXBpcm8udGVzdChpbnRlcm5ldF9hY2Nlc3MpDQpzaGFwaXJvLnRlc3Qobm9faW50ZXJuZXRfYWNjZXNzKQ0KYGBgDQoNClRoZSBTaGFwaXJvLVdpbGsgdGVzdCBjb25maXJtcyB0aGF0IHRoZSBkaXN0cmlidXRpb24gb2YgZmluYWwgZXhhbSBzY29yZXMgZm9yIHN0dWRlbnRzIHdpdGggYW5kIHdpdGhvdXQgaW50ZXJuZXQgYWNjZXNzIGlzIG5vdCBub3JtYWwsIHdpdGggYSBwLXZhbHVlIGxlc3MgdGhhbiAwLjA1Lg0KDQojIyBTdW1tYXJ5IG9mIERpc3RyaWJ1dGlvbiBBbmFseXNpcw0KDQpJbiBzdW1tYXJ5LCB0aGUgYW5hbHlzaXMgb2YgdGhlIGRpc3RyaWJ1dGlvbiBvZiBmaW5hbCBleGFtIHNjb3JlcyBhbmQgc3R1ZHkgaG91cnMgYWNyb3NzIHZhcmlvdXMgY2F0ZWdvcmllcyBzdWNoIGFzIHBhcmVudGFsIGludm9sdmVtZW50LCBhY2Nlc3MgdG8gcmVzb3VyY2VzLCBleHRyYWN1cnJpY3VsYXIgYWN0aXZpdGllcywgbW90aXZhdGlvbiBsZXZlbHMsIGludGVybmV0IGFjY2VzcywgZmFtaWx5IGluY29tZSwgdGVhY2hlciBxdWFsaXR5LCBzY2hvb2wgdHlwZSwgcGVlciBpbmZsdWVuY2UsIGxlYXJuaW5nIGRpc2FiaWxpdGllcywgcGFyZW50YWwgZWR1Y2F0aW9uIGxldmVscywgZGlzdGFuY2UgZnJvbSBob21lIHRvIHNjaG9vbCwgYW5kIGdlbmRlciBzaG93cyBubyBzaWduaWZpY2FudCBkaWZmZXJlbmNlcy4gVGhlIGRpc3RyaWJ1dGlvbnMgYXJlIGFwcHJveGltYXRlbHkgbm9ybWFsIGluIG1vc3QgY2FzZXMsIHdpdGggYSBmZXcgZXhjZXB0aW9ucyB3aGVyZSB0aGUgZGlzdHJpYnV0aW9ucyBhcmUgc2xpZ2h0bHkgc2tld2VkLiBPdmVyYWxsLCB0aGVzZSBmYWN0b3JzIGRvIG5vdCBoYXZlIGEgc2lnbmlmaWNhbnQgaW1wYWN0IG9uIHRoZSBmaW5hbCBleGFtIHNjb3JlcyBvciB0aGUgbnVtYmVyIG9mIGhvdXJzIHN0dWRlbnRzIHN0dWR5IHBlciB3ZWVrLg0KDQojIEF2ZXJhZ2UgbnVtYmVyIG9mIGhvdXJzIHN0dWRlbnRzIHN0dWR5IHBlciB3ZWVrDQoNCiMjIEF2ZXJhZ2UgTnVtYmVyIG9mIEhvdXJzIFN0dWRlbnRzIFN0dWR5IHBlciBXZWVrIChXaXRob3V0IENvbnNpZGVyaW5nIE90aGVyIEZhY3RvcnMpDQoNCk5leHQsIHdlIGV4cGxvcmUgdGhlIGF2ZXJhZ2UgbnVtYmVyIG9mIGhvdXJzIHN0dWRlbnRzIHN0dWR5IHBlciB3ZWVrIHdpdGhvdXQgY29uc2lkZXJpbmcgb3RoZXIgZmFjdG9ycy4NCmBgYHtyfQ0KIyBTdW1tYXJ5IHN0YXRpc3RpY3MgZm9yIHN0dWR5IGhvdXJzDQpzdW1tYXJ5KHN0dWRlbnRfZGF0YSRIb3Vyc19TdHVkaWVkKQ0KYGBgDQoNClRoZSBzdW1tYXJ5IHN0YXRpc3RpY3Mgc2hvdyB0aGF0IHRoZSBhdmVyYWdlIG51bWJlciBvZiBob3VycyBzdHVkZW50cyBzdHVkeSBwZXIgd2VlayBpcyBhcHByb3hpbWF0ZWx5IDE5Ljk4IGhvdXJzLiBXZSB3aWxsIG5vdyB2aXN1YWxpemUgdGhlIGRpc3RyaWJ1dGlvbiBvZiBzdHVkeSBob3VycyB1c2luZyBhIGhpc3RvZ3JhbS4NCmBgYHtyfQ0KIyBIaXN0b2dyYW0gb2Ygc3R1ZHkgaG91cnMNCmhpc3Qoc3R1ZGVudF9kYXRhJEhvdXJzX1N0dWRpZWQsIG1haW4gPSAiRGlzdHJpYnV0aW9uIG9mIFN0dWR5IEhvdXJzIiwgeGxhYiA9ICJTdHVkeSBIb3VycyIsIGNvbCA9ICJza3libHVlIiwgYm9yZGVyID0gImJsYWNrIikNCmBgYA0KDQpUaGUgZGlzdHJpYnV0aW9uIG9mIHN0dWR5IGhvdXJzIGlzIGFwcHJveGltYXRlbHkgbm9ybWFsLiBXZSB3aWxsIG5vdyB1c2UgbnVtZXJpY2FsIG1ldGhvZHMgdG8gY29uZmlybSB0aGUgbm9ybWFsaXR5IG9mIHRoZSBkaXN0cmlidXRpb24uDQoNCmBgYHtyfQ0KIyBTaGFwaXJvLVdpbGsgdGVzdCBmb3Igbm9ybWFsaXR5DQpzYW1wbGVfaG91cnNfc3R1ZGllZCA8LSBzdHVkZW50X2RhdGEkSG91cnNfU3R1ZGllZFtzYW1wbGUobnJvdyhzdHVkZW50X2RhdGEpLCAxMDApXQ0Kc2hhcGlyby50ZXN0KHNhbXBsZV9ob3Vyc19zdHVkaWVkKQ0KYGBgDQoNClRoZSBwLXZhbHVlIGlzIGdyZWF0ZXIgdGhhbiAwLjA1LCBpbmRpY2F0aW5nIHRoYXQgdGhlIGRpc3RyaWJ1dGlvbiBvZiBzdHVkeSBob3VycyBpcyBhcHByb3hpbWF0ZWx5IG5vcm1hbC4NCg0KIyMgQXZlcmFnZSBOdW1iZXIgb2YgSG91cnMgU3R1ZGVudHMgU3R1ZHkgcGVyIFdlZWsgKFBhcmVudGFsX0ludm9sdmVtZW50IENhdGVnb3J5KQ0KDQpOZXh0LCB3ZSB3aWxsIGV4cGxvcmUgdGhlIGF2ZXJhZ2UgbnVtYmVyIG9mIGhvdXJzIHN0dWRlbnRzIHN0dWR5IHBlciB3ZWVrIGJhc2VkIG9uIHBhcmVudGFsIGludm9sdmVtZW50IGxldmVscy4NCmBgYHtyfQ0KIyBTdW1tYXJ5IHN0YXRpc3RpY3MgZm9yIHN0dWR5IGhvdXJzIGJ5IHBhcmVudGFsIGludm9sdmVtZW50DQpzdW1tYXJ5KHN0dWRlbnRfZGF0YSRIb3Vyc19TdHVkaWVkW3N0dWRlbnRfZGF0YSRQYXJlbnRhbF9JbnZvbHZlbWVudCA9PSAiSGlnaCJdKQ0Kc3VtbWFyeShzdHVkZW50X2RhdGEkSG91cnNfU3R1ZGllZFtzdHVkZW50X2RhdGEkUGFyZW50YWxfSW52b2x2ZW1lbnQgPT0gIk1lZGl1bSJdKQ0Kc3VtbWFyeShzdHVkZW50X2RhdGEkSG91cnNfU3R1ZGllZFtzdHVkZW50X2RhdGEkUGFyZW50YWxfSW52b2x2ZW1lbnQgPT0gIkxvdyJdKQ0KYGBgDQoNClRoZSBzdW1tYXJ5IHN0YXRpc3RpY3Mgb2YgdGhlIGF2ZXJhZ2UgbnVtYmVyIG9mIGhvdXJzIHN0dWRlbnRzIHN0dWR5IHBlciB3ZWVrIGJhc2VkIG9uIHBhcmVudGFsIGludm9sdmVtZW50IGxldmVscyBkbyBub3Qgc2hvdyBzaWduaWZpY2FudCBkaWZmZXJlbmNlcy4gV2Ugd2lsbCBub3cgdXNlIEFOT1ZBIHRvIHRlc3QgZm9yIGRpZmZlcmVuY2VzIGluIHN0dWR5IGhvdXJzIGJhc2VkIG9uIHBhcmVudGFsIGludm9sdmVtZW50IGxldmVscy4gQnV0IGZpcnN0LCB3ZSBuZWVkIHRvIGNoZWNrIHRoZSBhc3N1bXB0aW9ucyBvZiBBTk9WQS4NCmBgYHtyfQ0KIyBTYW1wbGUgdGhlIGRhdGENCmhpZ2hfcGFyZW50YWxfaW52b2x2ZW1lbnQgPC0gc3R1ZGVudF9kYXRhJEhvdXJzX1N0dWRpZWRbc3R1ZGVudF9kYXRhJFBhcmVudGFsX0ludm9sdmVtZW50ID09ICJIaWdoIl1bc2FtcGxlKHN1bShzdHVkZW50X2RhdGEkUGFyZW50YWxfSW52b2x2ZW1lbnQgPT0gIkhpZ2giKSwgMTAwKV0NCm1lZGl1bV9wYXJlbnRhbF9pbnZvbHZlbWVudCA8LSBzdHVkZW50X2RhdGEkSG91cnNfU3R1ZGllZFtzdHVkZW50X2RhdGEkUGFyZW50YWxfSW52b2x2ZW1lbnQgPT0gIk1lZGl1bSJdW3NhbXBsZShzdW0oc3R1ZGVudF9kYXRhJFBhcmVudGFsX0ludm9sdmVtZW50ID09ICJNZWRpdW0iKSwgMTAwKV0NCmxvd19wYXJlbnRhbF9pbnZvbHZlbWVudCA8LSBzdHVkZW50X2RhdGEkSG91cnNfU3R1ZGllZFtzdHVkZW50X2RhdGEkUGFyZW50YWxfSW52b2x2ZW1lbnQgPT0gIkxvdyJdW3NhbXBsZShzdW0oc3R1ZGVudF9kYXRhJFBhcmVudGFsX0ludm9sdmVtZW50ID09ICJMb3ciKSwgMTAwKV0NCg0KIyBIaXN0b2dyYW0gb2Ygc3R1ZHkgaG91cnMgYnkgcGFyZW50YWwgaW52b2x2ZW1lbnQNCnBhcihtZnJvdyA9IGMoMSwgMykpDQpoaXN0KGhpZ2hfcGFyZW50YWxfaW52b2x2ZW1lbnQsIG1haW4gPSAiSGlnaCBQYXJlbnRhbCBJbnZvbHZlbWVudCIsIHhsYWIgPSAiU3R1ZHkgSG91cnMiLCBjb2wgPSAic2t5Ymx1ZSIsIGJvcmRlciA9ICJibGFjayIpDQpoaXN0KG1lZGl1bV9wYXJlbnRhbF9pbnZvbHZlbWVudCwgbWFpbiA9ICJNZWRpdW0gUGFyZW50YWwgSW52b2x2ZW1lbnQiLCB4bGFiID0gIlN0dWR5IEhvdXJzIiwgY29sID0gInNreWJsdWUiLCBib3JkZXIgPSAiYmxhY2siKQ0KaGlzdChsb3dfcGFyZW50YWxfaW52b2x2ZW1lbnQsIG1haW4gPSAiTG93IFBhcmVudGFsIEludm9sdmVtZW50IiwgeGxhYiA9ICJTdHVkeSBIb3VycyIsIGNvbCA9ICJza3libHVlIiwgYm9yZGVyID0gImJsYWNrIikNCg0KDQojIENoZWNrIGFzc3VtcHRpb25zIG9mIEFOT1ZBDQpzaGFwaXJvLnRlc3QoaGlnaF9wYXJlbnRhbF9pbnZvbHZlbWVudCkNCnNoYXBpcm8udGVzdChtZWRpdW1fcGFyZW50YWxfaW52b2x2ZW1lbnQpDQpzaGFwaXJvLnRlc3QobG93X3BhcmVudGFsX2ludm9sdmVtZW50KQ0KYGBgDQoNCkJvdGggdGhlIGhpc3RvZ3JhbXMgYW5kIHRoZSBTaGFwaXJvLVdpbGsgdGVzdCBzaG93IHRoYXQgdGhlIGRpc3RyaWJ1dGlvbiBvZiBzdHVkeSBob3VycyBpcyBhcHByb3hpbWF0ZWx5IG5vcm1hbCBmb3IgYWxsIHN0dWRlbnRzLiBXZSB3aWxsIG5vdyB1c2UgQU5PVkEgdG8gdGVzdCBmb3IgZGlmZmVyZW5jZXMgaW4gc3R1ZHkgaG91cnMgYmFzZWQgb24gcGFyZW50YWwgaW52b2x2ZW1lbnQgbGV2ZWxzLg0KYGBge3J9DQojIEFOT1ZBIHRlc3QgZm9yIHN0dWR5IGhvdXJzIGJ5IHBhcmVudGFsIGludm9sdmVtZW50DQphbm92YV9wYXJlbnRhbF9pbnZvbHZlbWVudCA8LSBhb3YoSG91cnNfU3R1ZGllZCB+IFBhcmVudGFsX0ludm9sdmVtZW50LCBkYXRhID0gc3R1ZGVudF9kYXRhKQ0Kc3VtbWFyeShhbm92YV9wYXJlbnRhbF9pbnZvbHZlbWVudCkNCmBgYA0KDQpUaGUgQU5PVkEgdGVzdCBzaG93cyB0aGF0IHRoZXJlIGlzIG5vIHNpZ25pZmljYW50IGRpZmZlcmVuY2UgaW4gdGhlIGF2ZXJhZ2UgbnVtYmVyIG9mIGhvdXJzIHN0dWRlbnRzIHN0dWR5IHBlciB3ZWVrIGJhc2VkIG9uIHBhcmVudGFsIGludm9sdmVtZW50IGxldmVscywgd2l0aCBhIHAtdmFsdWUgZ3JlYXRlciB0aGFuIDAuMDUuIFRoaXMgaW5kaWNhdGVzIHRoYXQgcGFyZW50YWwgaW52b2x2ZW1lbnQgZG9lcyBub3QgaGF2ZSBhIHNpZ25pZmljYW50IGltcGFjdCBvbiB0aGUgbnVtYmVyIG9mIGhvdXJzIHN0dWRlbnRzIHN0dWR5IHBlciB3ZWVrLg0KDQojIyBBdmVyYWdlIE51bWJlciBvZiBIb3VycyBTdHVkZW50cyBTdHVkeSBwZXIgV2VlayAoQWNjZXNzX3RvX1Jlc291cmNlcyBDYXRlZ29yeSkNCg0KV2Ugbm93IGV4cGxvcmUgdGhlIGF2ZXJhZ2UgbnVtYmVyIG9mIGhvdXJzIHN0dWRlbnRzIHN0dWR5IHBlciB3ZWVrIGJhc2VkIG9uIGFjY2VzcyB0byByZXNvdXJjZXMuDQoNCmBgYHtyfQ0Kc3VtbWFyeShzdHVkZW50X2RhdGEkSG91cnNfU3R1ZGllZFtzdHVkZW50X2RhdGEkQWNjZXNzX3RvX1Jlc291cmNlcyA9PSAiSGlnaCJdKQ0Kc3VtbWFyeShzdHVkZW50X2RhdGEkSG91cnNfU3R1ZGllZFtzdHVkZW50X2RhdGEkQWNjZXNzX3RvX1Jlc291cmNlcyA9PSAiTWVkaXVtIl0pDQpzdW1tYXJ5KHN0dWRlbnRfZGF0YSRIb3Vyc19TdHVkaWVkW3N0dWRlbnRfZGF0YSRBY2Nlc3NfdG9fUmVzb3VyY2VzID09ICJMb3ciXSkNCmBgYA0KDQpUaGUgc3VtbWFyeSBzdGF0aXN0aWNzIG9mIHRoZSBhdmVyYWdlIG51bWJlciBvZiBob3VycyBzdHVkZW50cyBzdHVkeSBwZXIgd2VlayBiYXNlZCBvbiBhY2Nlc3MgdG8gcmVzb3VyY2VzIGRvIG5vdCBzaG93IHNpZ25pZmljYW50IGRpZmZlcmVuY2VzLiBXZSB3aWxsIG5vdyB1c2UgQU5PVkEgdG8gdGVzdCBmb3IgZGlmZmVyZW5jZXMgaW4gc3R1ZHkgaG91cnMgYmFzZWQgb24gYWNjZXNzIHRvIHJlc291cmNlcy4gQnV0IGZpcnN0LCB3ZSBuZWVkIHRvIGNoZWNrIHRoZSBhc3N1bXB0aW9ucyBvZiBBTk9WQS4NCg0KYGBge3J9DQojIFNhbXBsZSB0aGUgZGF0YQ0KaGlnaF9hY2Nlc3NfdG9fcmVzb3VyY2VzIDwtIHN0dWRlbnRfZGF0YSRIb3Vyc19TdHVkaWVkW3N0dWRlbnRfZGF0YSRBY2Nlc3NfdG9fUmVzb3VyY2VzID09ICJIaWdoIl1bc2FtcGxlKHN1bShzdHVkZW50X2RhdGEkQWNjZXNzX3RvX1Jlc291cmNlcyA9PSAiSGlnaCIpLCAxMDApXQ0KbWVkaXVtX2FjY2Vzc190b19yZXNvdXJjZXMgPC0gc3R1ZGVudF9kYXRhJEhvdXJzX1N0dWRpZWRbc3R1ZGVudF9kYXRhJEFjY2Vzc190b19SZXNvdXJjZXMgPT0gIk1lZGl1bSJdW3NhbXBsZShzdW0oc3R1ZGVudF9kYXRhJEFjY2Vzc190b19SZXNvdXJjZXMgPT0gIk1lZGl1bSIpLCAxMDApXQ0KbG93X2FjY2Vzc190b19yZXNvdXJjZXMgPC0gc3R1ZGVudF9kYXRhJEhvdXJzX1N0dWRpZWRbc3R1ZGVudF9kYXRhJEFjY2Vzc190b19SZXNvdXJjZXMgPT0gIkxvdyJdW3NhbXBsZShzdW0oc3R1ZGVudF9kYXRhJEFjY2Vzc190b19SZXNvdXJjZXMgPT0gIkxvdyIpLCAxMDApXQ0KDQojIEhpc3RvZ3JhbSBvZiBzdHVkeSBob3VycyBieSBhY2Nlc3MgdG8gcmVzb3VyY2VzDQpwYXIobWZyb3cgPSBjKDEsIDMpKQ0KaGlzdChoaWdoX2FjY2Vzc190b19yZXNvdXJjZXMsIG1haW4gPSAiSGlnaCBBY2Nlc3MgdG8gUmVzb3VyY2VzIiwgeGxhYiA9ICJTdHVkeSBIb3VycyIsIGNvbCA9ICJza3libHVlIiwgYm9yZGVyID0gImJsYWNrIikNCmhpc3QobWVkaXVtX2FjY2Vzc190b19yZXNvdXJjZXMsIG1haW4gPSAiTWVkaXVtIEFjY2VzcyB0byBSZXNvdXJjZXMiLCB4bGFiID0gIlN0dWR5IEhvdXJzIiwgY29sID0gInNreWJsdWUiLCBib3JkZXIgPSAiYmxhY2siKQ0KaGlzdChsb3dfYWNjZXNzX3RvX3Jlc291cmNlcywgbWFpbiA9ICJMb3cgQWNjZXNzIHRvIFJlc291cmNlcyIsIHhsYWIgPSAiU3R1ZHkgSG91cnMiLCBjb2wgPSAic2t5Ymx1ZSIsIGJvcmRlciA9ICJibGFjayIpDQoNCiMgQ2hlY2sgYXNzdW1wdGlvbnMgb2YgQU5PVkENCnNoYXBpcm8udGVzdChoaWdoX2FjY2Vzc190b19yZXNvdXJjZXMpDQpzaGFwaXJvLnRlc3QobWVkaXVtX2FjY2Vzc190b19yZXNvdXJjZXMpDQpzaGFwaXJvLnRlc3QobG93X2FjY2Vzc190b19yZXNvdXJjZXMpDQpgYGANCg0KQm90aCB0aGUgaGlzdG9ncmFtcyBhbmQgdGhlIFNoYXBpcm8tV2lsayB0ZXN0IHNob3cgdGhhdCB0aGUgZGlzdHJpYnV0aW9uIG9mIHN0dWR5IGhvdXJzIGlzIGFwcHJveGltYXRlbHkgbm9ybWFsIGZvciBhbGwgc3R1ZGVudHMuIFdlIHdpbGwgbm93IHVzZSBBTk9WQSB0byB0ZXN0IGZvciBkaWZmZXJlbmNlcyBpbiBzdHVkeSBob3VycyBiYXNlZCBvbiBhY2Nlc3MgdG8gcmVzb3VyY2VzLg0KYGBge3J9DQojIEFOT1ZBIHRlc3QgZm9yIHN0dWR5IGhvdXJzIGJ5IGFjY2VzcyB0byByZXNvdXJjZXMNCmFub3ZhX2FjY2Vzc190b19yZXNvdXJjZXMgPC0gYW92KEhvdXJzX1N0dWRpZWQgfiBBY2Nlc3NfdG9fUmVzb3VyY2VzLCBkYXRhID0gc3R1ZGVudF9kYXRhKQ0Kc3VtbWFyeShhbm92YV9hY2Nlc3NfdG9fcmVzb3VyY2VzKQ0KYGBgDQoNClRoZSBBTk9WQSB0ZXN0IHNob3dzIHRoYXQgdGhlcmUgaXMgbm8gc2lnbmlmaWNhbnQgZGlmZmVyZW5jZSBpbiB0aGUgYXZlcmFnZSBudW1iZXIgb2YgaG91cnMgc3R1ZGVudHMgc3R1ZHkgcGVyIHdlZWsgYmFzZWQgb24gYWNjZXNzIHRvIHJlc291cmNlcywgd2l0aCBhIHAtdmFsdWUgZ3JlYXRlciB0aGFuIDAuMDUuIFRoaXMgaW5kaWNhdGVzIHRoYXQgYWNjZXNzIHRvIHJlc291cmNlcyBkb2VzIG5vdCBoYXZlIGEgc2lnbmlmaWNhbnQgaW1wYWN0IG9uIHRoZSBudW1iZXIgb2YgaG91cnMgc3R1ZGVudHMgc3R1ZHkgcGVyIHdlZWsuDQoNCiMjIEF2ZXJhZ2UgTnVtYmVyIG9mIEhvdXJzIFN0dWRlbnRzIFN0dWR5IHBlciBXZWVrIChFeHRyYWN1cnJpY3VsYXJfQWN0aXZpdGllcyBDYXRlZ29yeSkNCg0KTmV4dCwgd2UgZXhwbG9yZSB0aGUgYXZlcmFnZSBudW1iZXIgb2YgaG91cnMgc3R1ZGVudHMgc3R1ZHkgcGVyIHdlZWsgYmFzZWQgb24gcGFydGljaXBhdGlvbiBpbiBleHRyYWN1cnJpY3VsYXIgYWN0aXZpdGllcy4NCmBgYHtyfQ0KIyBTdW1tYXJ5IHN0YXRpc3RpY3MgZm9yIHN0dWR5IGhvdXJzIGJ5IGV4dHJhY3VycmljdWxhciBhY3Rpdml0aWVzDQpzdW1tYXJ5KHN0dWRlbnRfZGF0YSRIb3Vyc19TdHVkaWVkW3N0dWRlbnRfZGF0YSRFeHRyYWN1cnJpY3VsYXJfQWN0aXZpdGllcyA9PSAiWWVzIl0pDQpzdW1tYXJ5KHN0dWRlbnRfZGF0YSRIb3Vyc19TdHVkaWVkW3N0dWRlbnRfZGF0YSRFeHRyYWN1cnJpY3VsYXJfQWN0aXZpdGllcyA9PSAiTm8iXSkNCmBgYA0KDQpUaGUgc3VtbWFyeSBzdGF0aXN0aWNzIG9mIHRoZSBhdmVyYWdlIG51bWJlciBvZiBob3VycyBzdHVkZW50cyBzdHVkeSBwZXIgd2VlayBiYXNlZCBvbiBwYXJ0aWNpcGF0aW9uIGluIGV4dHJhY3VycmljdWxhciBhY3Rpdml0aWVzIHNob3cgbm8gc2lnbmlmaWNhbnQgZGlmZmVyZW5jZXMuIFdlIHdpbGwgbm93IHVzZSB0LXRlc3QgdG8gdGVzdCBmb3IgZGlmZmVyZW5jZXMgaW4gc3R1ZHkgaG91cnMgYmFzZWQgb24gcGFydGljaXBhdGlvbiBpbiBleHRyYWN1cnJpY3VsYXIgYWN0aXZpdGllcy4gQnV0IGZpcnN0LCB3ZSBuZWVkIHRvIGNoZWNrIHRoZSBhc3N1bXB0aW9ucyBvZiB0LXRlc3QuDQoNCmBgYHtyfQ0KIyBTYW1wbGUgdGhlIGRhdGENCnBhcnRpY2lwYXRlX2V4dHJhY3VycmljdWxhciA8LSBzdHVkZW50X2RhdGEkSG91cnNfU3R1ZGllZFtzdHVkZW50X2RhdGEkRXh0cmFjdXJyaWN1bGFyX0FjdGl2aXRpZXMgPT0gIlllcyJdW3NhbXBsZShzdW0oc3R1ZGVudF9kYXRhJEV4dHJhY3VycmljdWxhcl9BY3Rpdml0aWVzID09ICJZZXMiKSwgMTAwKV0NCmRvX25vdF9wYXJ0aWNpcGF0ZV9leHRyYWN1cnJpY3VsYXIgPC0gc3R1ZGVudF9kYXRhJEhvdXJzX1N0dWRpZWRbc3R1ZGVudF9kYXRhJEV4dHJhY3VycmljdWxhcl9BY3Rpdml0aWVzID09ICJObyJdW3NhbXBsZShzdW0oc3R1ZGVudF9kYXRhJEV4dHJhY3VycmljdWxhcl9BY3Rpdml0aWVzID09ICJObyIpLCAxMDApXQ0KDQojIEhpc3RvZ3JhbSBvZiBzdHVkeSBob3VycyBieSBleHRyYWN1cnJpY3VsYXIgYWN0aXZpdGllcw0KcGFyKG1mcm93ID0gYygxLCAyKSkNCmhpc3QocGFydGljaXBhdGVfZXh0cmFjdXJyaWN1bGFyLCBtYWluID0gIkV4dHJhY3VycmljdWxhciBBY3Rpdml0aWVzIiwgeGxhYiA9ICJTdHVkeSBIb3VycyIsIGNvbCA9ICJza3libHVlIiwgYm9yZGVyID0gImJsYWNrIikNCmhpc3QoZG9fbm90X3BhcnRpY2lwYXRlX2V4dHJhY3VycmljdWxhciwgbWFpbiA9ICJObyBFeHRyYWN1cnJpY3VsYXIgQWN0aXZpdGllcyIsIHhsYWIgPSAiU3R1ZHkgSG91cnMiLCBjb2wgPSAic2t5Ymx1ZSIsIGJvcmRlciA9ICJibGFjayIpDQoNCiMgQ2hlY2sgYXNzdW1wdGlvbnMgb2YgdC10ZXN0DQpzaGFwaXJvLnRlc3QocGFydGljaXBhdGVfZXh0cmFjdXJyaWN1bGFyKQ0Kc2hhcGlyby50ZXN0KGRvX25vdF9wYXJ0aWNpcGF0ZV9leHRyYWN1cnJpY3VsYXIpDQpgYGANCg0KQm90aCB0aGUgaGlzdG9ncmFtcyBhbmQgdGhlIFNoYXBpcm8tV2lsayB0ZXN0IHNob3cgdGhhdCB0aGUgZGlzdHJpYnV0aW9uIG9mIHN0dWR5IGhvdXJzIGlzIGFwcHJveGltYXRlbHkgbm9ybWFsIGZvciBhbGwgc3R1ZGVudHMuIFdlIHdpbGwgbm93IHVzZSB0LXRlc3QgdG8gdGVzdCBmb3IgZGlmZmVyZW5jZXMgaW4gc3R1ZHkgaG91cnMgYmFzZWQgb24gcGFydGljaXBhdGlvbiBpbiBleHRyYWN1cnJpY3VsYXIgYWN0aXZpdGllcy4NCg0KYGBge3J9DQojIHQtdGVzdCB0ZXN0IGZvciBzdHVkeSBob3VycyBieSBleHRyYWN1cnJpY3VsYXIgYWN0aXZpdGllcw0KdC50ZXN0KHBhcnRpY2lwYXRlX2V4dHJhY3VycmljdWxhciwgZG9fbm90X3BhcnRpY2lwYXRlX2V4dHJhY3VycmljdWxhcikNCmBgYA0KDQpUaGUgdC10ZXN0IHNob3dzIHRoYXQgdGhlcmUgaXMgbm8gc2lnbmlmaWNhbnQgZGlmZmVyZW5jZSBpbiB0aGUgYXZlcmFnZSBudW1iZXIgb2YgaG91cnMgc3R1ZGVudHMgc3R1ZHkgcGVyIHdlZWsgYmFzZWQgb24gcGFydGljaXBhdGlvbiBpbiBleHRyYWN1cnJpY3VsYXIgYWN0aXZpdGllcywgd2l0aCBhIHAtdmFsdWUgZ3JlYXRlciB0aGFuIDAuMDUuIFRoaXMgaW5kaWNhdGVzIHRoYXQgcGFydGljaXBhdGlvbiBpbiBleHRyYWN1cnJpY3VsYXIgYWN0aXZpdGllcyBkb2VzIG5vdCBoYXZlIGEgc2lnbmlmaWNhbnQgaW1wYWN0IG9uIHRoZSBudW1iZXIgb2YgaG91cnMgc3R1ZGVudHMgc3R1ZHkgcGVyIHdlZWsuDQoNCiMjIEF2ZXJhZ2UgTnVtYmVyIG9mIEhvdXJzIFN0dWRlbnRzIFN0dWR5IHBlciBXZWVrIChNb3RpdmF0aW9uX0xldmVsIENhdGVnb3J5KQ0KDQpOZXh0LCB3ZSBleHBsb3JlIHRoZSBhdmVyYWdlIG51bWJlciBvZiBob3VycyBzdHVkZW50cyBzdHVkeSBwZXIgd2VlayBiYXNlZCBvbiBtb3RpdmF0aW9uIGxldmVscy4NCmBgYHtyfQ0KIyBTdW1tYXJ5IHN0YXRpc3RpY3MgZm9yIHN0dWR5IGhvdXJzIGJ5IG1vdGl2YXRpb24gbGV2ZWwNCnN1bW1hcnkoc3R1ZGVudF9kYXRhJEhvdXJzX1N0dWRpZWRbc3R1ZGVudF9kYXRhJE1vdGl2YXRpb25fTGV2ZWwgPT0gIkhpZ2giXSkNCnN1bW1hcnkoc3R1ZGVudF9kYXRhJEhvdXJzX1N0dWRpZWRbc3R1ZGVudF9kYXRhJE1vdGl2YXRpb25fTGV2ZWwgPT0gIk1lZGl1bSJdKQ0Kc3VtbWFyeShzdHVkZW50X2RhdGEkSG91cnNfU3R1ZGllZFtzdHVkZW50X2RhdGEkTW90aXZhdGlvbl9MZXZlbCA9PSAiTG93Il0pDQpgYGANCg0KVGhlIHN1bW1hcnkgc3RhdGlzdGljcyBvZiB0aGUgYXZlcmFnZSBudW1iZXIgb2YgaG91cnMgc3R1ZGVudHMgc3R1ZHkgcGVyIHdlZWsgYmFzZWQgb24gbW90aXZhdGlvbiBsZXZlbHMgc2hvdyBubyBzaWduaWZpY2FudCBkaWZmZXJlbmNlcy4gV2Ugd2lsbCBub3cgdXNlIEFOT1ZBIHRvIHRlc3QgZm9yIGRpZmZlcmVuY2VzIGluIHN0dWR5IGhvdXJzIGJhc2VkIG9uIG1vdGl2YXRpb24gbGV2ZWxzLiBCdXQgZmlyc3QsIHdlIG5lZWQgdG8gY2hlY2sgdGhlIGFzc3VtcHRpb25zIG9mIEFOT1ZBLg0KDQpgYGB7cn0NCiMgU2FtcGxlIHRoZSBkYXRhDQpoaWdoX21vdGl2YXRpb24gPC0gc3R1ZGVudF9kYXRhJEhvdXJzX1N0dWRpZWRbc3R1ZGVudF9kYXRhJE1vdGl2YXRpb25fTGV2ZWwgPT0gIkhpZ2giXVtzYW1wbGUoc3VtKHN0dWRlbnRfZGF0YSRNb3RpdmF0aW9uX0xldmVsID09ICJIaWdoIiksIDEwMCldDQptZWRpdW1fbW90aXZhdGlvbiA8LSBzdHVkZW50X2RhdGEkSG91cnNfU3R1ZGllZFtzdHVkZW50X2RhdGEkTW90aXZhdGlvbl9MZXZlbCA9PSAiTWVkaXVtIl1bc2FtcGxlKHN1bShzdHVkZW50X2RhdGEkTW90aXZhdGlvbl9MZXZlbCA9PSAiTWVkaXVtIiksIDEwMCldDQpsb3dfbW90aXZhdGlvbiA8LSBzdHVkZW50X2RhdGEkSG91cnNfU3R1ZGllZFtzdHVkZW50X2RhdGEkTW90aXZhdGlvbl9MZXZlbCA9PSAiTG93Il1bc2FtcGxlKHN1bShzdHVkZW50X2RhdGEkTW90aXZhdGlvbl9MZXZlbCA9PSAiTG93IiksIDEwMCldDQoNCiMgSGlzdG9ncmFtIG9mIHN0dWR5IGhvdXJzIGJ5IG1vdGl2YXRpb24gbGV2ZWwNCnBhcihtZnJvdyA9IGMoMSwgMykpDQpoaXN0KGhpZ2hfbW90aXZhdGlvbiwgbWFpbiA9ICJIaWdoIE1vdGl2YXRpb24gTGV2ZWwiLCB4bGFiID0gIlN0dWR5IEhvdXJzIiwgY29sID0gInNreWJsdWUiLCBib3JkZXIgPSAiYmxhY2siKQ0KaGlzdChtZWRpdW1fbW90aXZhdGlvbiwgbWFpbiA9ICJNZWRpdW0gTW90aXZhdGlvbiBMZXZlbCIsIHhsYWIgPSAiU3R1ZHkgSG91cnMiLCBjb2wgPSAic2t5Ymx1ZSIsIGJvcmRlciA9ICJibGFjayIpDQpoaXN0KGxvd19tb3RpdmF0aW9uLCBtYWluID0gIkxvdyBNb3RpdmF0aW9uIExldmVsIiwgeGxhYiA9ICJTdHVkeSBIb3VycyIsIGNvbCA9ICJza3libHVlIiwgYm9yZGVyID0gImJsYWNrIikNCg0KIyBDaGVjayBhc3N1bXB0aW9ucyBvZiBBTk9WQQ0Kc2hhcGlyby50ZXN0KGhpZ2hfbW90aXZhdGlvbikNCnNoYXBpcm8udGVzdChtZWRpdW1fbW90aXZhdGlvbikNCnNoYXBpcm8udGVzdChsb3dfbW90aXZhdGlvbikNCmBgYA0KDQpTaGFwaXJvLVdpbGsgdGVzdCBzaG93cyB0aGF0IHRoZSBkaXN0cmlidXRpb24gb2Ygc3R1ZHkgaG91cnMgb2Ygc3R1ZGVudHMgd2l0aCBtZWRpdW0gbW90aXZhdGlvbiBpcyBub3Qgbm9ybWFsLCB3aXRoIGEgcC12YWx1ZSBsZXNzIHRoYW4gMC4wNS4gV2Ugd2lsbCBub3cgdXNlIEtydWtzYWwtV2FsbGlzIHRlc3QgdG8gdGVzdCBmb3IgZGlmZmVyZW5jZXMgaW4gc3R1ZHkgaG91cnMgYmFzZWQgb24gbW90aXZhdGlvbiBsZXZlbHMuDQoNCmBgYHtyfQ0KIyBLcnVza2FsLVdhbGxpcyB0ZXN0IGZvciBzdHVkeSBob3VycyBieSBtb3RpdmF0aW9uIGxldmVsDQprcnVza2FsLnRlc3QoSG91cnNfU3R1ZGllZCB+IE1vdGl2YXRpb25fTGV2ZWwsIGRhdGEgPSBzdHVkZW50X2RhdGEpDQpgYGANCg0KVGhlIEtydXNrYWwtV2FsbGlzIHRlc3Qgc2hvd3MgdGhhdCB0aGVyZSBpcyBubyBzaWduaWZpY2FudCBkaWZmZXJlbmNlIGluIHRoZSBhdmVyYWdlIG51bWJlciBvZiBob3VycyBzdHVkZW50cyBzdHVkeSBwZXIgd2VlayBiYXNlZCBvbiBtb3RpdmF0aW9uIGxldmVscywgd2l0aCBhIHAtdmFsdWUgZ3JlYXRlciB0aGFuIDAuMDUuIFRoaXMgaW5kaWNhdGVzIHRoYXQgbW90aXZhdGlvbiBsZXZlbHMgZG8gbm90IGhhdmUgYSBzaWduaWZpY2FudCBpbXBhY3Qgb24gdGhlIG51bWJlciBvZiBob3VycyBzdHVkZW50cyBzdHVkeSBwZXIgd2Vlay4NCg0KIyMgQXZlcmFnZSBOdW1iZXIgb2YgSG91cnMgU3R1ZGVudHMgU3R1ZHkgcGVyIFdlZWsgKEludGVybmV0IEFjY2VzcyBDYXRlZ29yeSkNCg0KTmV4dCwgd2UgZXhwbG9yZSB0aGUgYXZlcmFnZSBudW1iZXIgb2YgaG91cnMgc3R1ZGVudHMgc3R1ZHkgcGVyIHdlZWsgYmFzZWQgb24gaW50ZXJuZXQgYWNjZXNzLg0KDQpgYGB7cn0NCiMgU3VtbWFyeSBzdGF0aXN0aWNzIGZvciBzdHVkeSBob3VycyBieSBpbnRlcm5ldCBhY2Nlc3MNCnN1bW1hcnkoc3R1ZGVudF9kYXRhJEhvdXJzX1N0dWRpZWRbc3R1ZGVudF9kYXRhJEludGVybmV0X0FjY2VzcyA9PSAiWWVzIl0pDQpzdW1tYXJ5KHN0dWRlbnRfZGF0YSRIb3Vyc19TdHVkaWVkW3N0dWRlbnRfZGF0YSRJbnRlcm5ldF9BY2Nlc3MgPT0gIk5vIl0pDQpgYGANCg0KVGhlIHN1bW1hcnkgc3RhdGlzdGljcyBvZiB0aGUgYXZlcmFnZSBudW1iZXIgb2YgaG91cnMgc3R1ZGVudHMgc3R1ZHkgcGVyIHdlZWsgYmFzZWQgb24gaW50ZXJuZXQgYWNjZXNzIHNob3cgbm8gc2lnbmlmaWNhbnQgZGlmZmVyZW5jZXMuIFdlIHdpbGwgbm93IHVzZSB0LXRlc3QgdG8gdGVzdCBmb3IgZGlmZmVyZW5jZXMgaW4gc3R1ZHkgaG91cnMgYmFzZWQgb24gaW50ZXJuZXQgYWNjZXNzLiBCdXQgZmlyc3QsIHdlIG5lZWQgdG8gY2hlY2sgdGhlIGFzc3VtcHRpb25zIG9mIHQtdGVzdC4NCg0KYGBge3J9DQojIFNhbXBsZSB0aGUgZGF0YQ0KaW50ZXJuZXRfYWNjZXNzIDwtIHN0dWRlbnRfZGF0YSRIb3Vyc19TdHVkaWVkW3N0dWRlbnRfZGF0YSRJbnRlcm5ldF9BY2Nlc3MgPT0gIlllcyJdW3NhbXBsZShzdW0oc3R1ZGVudF9kYXRhJEludGVybmV0X0FjY2VzcyA9PSAiWWVzIiksIDEwMCldDQpub19pbnRlcm5ldF9hY2Nlc3MgPC0gc3R1ZGVudF9kYXRhJEhvdXJzX1N0dWRpZWRbc3R1ZGVudF9kYXRhJEludGVybmV0X0FjY2VzcyA9PSAiTm8iXVtzYW1wbGUoc3VtKHN0dWRlbnRfZGF0YSRJbnRlcm5ldF9BY2Nlc3MgPT0gIk5vIiksIDEwMCldDQoNCiMgSGlzdG9ncmFtIG9mIHN0dWR5IGhvdXJzIGJ5IGludGVybmV0IGFjY2Vzcw0KcGFyKG1mcm93ID0gYygxLCAyKSkNCmhpc3QoaW50ZXJuZXRfYWNjZXNzLCBtYWluID0gIkludGVybmV0IEFjY2VzcyIsIHhsYWIgPSAiU3R1ZHkgSG91cnMiLCBjb2wgPSAic2t5Ymx1ZSIsIGJvcmRlciA9ICJibGFjayIpDQpoaXN0KG5vX2ludGVybmV0X2FjY2VzcywgbWFpbiA9ICJObyBJbnRlcm5ldCBBY2Nlc3MiLCB4bGFiID0gIlN0dWR5IEhvdXJzIiwgY29sID0gInNreWJsdWUiLCBib3JkZXIgPSAiYmxhY2siKQ0KDQojIENoZWNrIGFzc3VtcHRpb25zIG9mIHQtdGVzdA0Kc2hhcGlyby50ZXN0KGludGVybmV0X2FjY2VzcykNCnNoYXBpcm8udGVzdChub19pbnRlcm5ldF9hY2Nlc3MpDQpgYGANCg0KQm90aCB0aGUgaGlzdG9ncmFtcyBhbmQgdGhlIFNoYXBpcm8tV2lsayB0ZXN0IHNob3cgdGhhdCB0aGUgZGlzdHJpYnV0aW9uIG9mIHN0dWR5IGhvdXJzIGlzIGFwcHJveGltYXRlbHkgbm9ybWFsIGZvciBhbGwgc3R1ZGVudHMuIFdlIHdpbGwgbm93IHVzZSB0LXRlc3QgdG8gdGVzdCBmb3IgZGlmZmVyZW5jZXMgaW4gc3R1ZHkgaG91cnMgYmFzZWQgb24gaW50ZXJuZXQgYWNjZXNzLg0KDQpgYGB7cn0NCiMgdC10ZXN0IHRlc3QgZm9yIHN0dWR5IGhvdXJzIGJ5IGludGVybmV0IGFjY2Vzcw0KdC50ZXN0KGludGVybmV0X2FjY2Vzcywgbm9faW50ZXJuZXRfYWNjZXNzKQ0KYGBgDQoNClRoZSBwLXZhbHVlIGlzIGxlc3MgdGhhbiAwLjA1LCBpbmRpY2F0aW5nIHRoYXQgdGhlcmUgaXMgYSBzaWduaWZpY2FudCBkaWZmZXJlbmNlIGluIHRoZSBhdmVyYWdlIG51bWJlciBvZiBob3VycyBzdHVkZW50cyBzdHVkeSBwZXIgd2VlayBiYXNlZCBvbiBpbnRlcm5ldCBhY2Nlc3MuIFRoaXMgc3VnZ2VzdHMgdGhhdCBpbnRlcm5ldCBhY2Nlc3MgaGFzIGEgc2lnbmlmaWNhbnQgaW1wYWN0IG9uIHRoZSBudW1iZXIgb2YgaG91cnMgc3R1ZGVudHMgc3R1ZHkgcGVyIHdlZWsuDQoNCiMjIEF2ZXJhZ2UgTnVtYmVyIG9mIEhvdXJzIFN0dWRlbnRzIFN0dWR5IHBlciBXZWVrIChGYW1pbHkgSW5jb21lIENhdGVnb3J5KQ0KDQpOZXh0LCB3ZSBleHBsb3JlIHRoZSBhdmVyYWdlIG51bWJlciBvZiBob3VycyBzdHVkZW50cyBzdHVkeSBwZXIgd2VlayBiYXNlZCBvbiBmYW1pbHkgaW5jb21lIGxldmVscy4NCg0KYGBge3J9DQojIFN1bW1hcnkgc3RhdGlzdGljcyBmb3Igc3R1ZHkgaG91cnMgYnkgZmFtaWx5IGluY29tZQ0Kc3VtbWFyeShzdHVkZW50X2RhdGEkSG91cnNfU3R1ZGllZFtzdHVkZW50X2RhdGEkRmFtaWx5X0luY29tZSA9PSAiTG93Il0pDQpzdW1tYXJ5KHN0dWRlbnRfZGF0YSRIb3Vyc19TdHVkaWVkW3N0dWRlbnRfZGF0YSRGYW1pbHlfSW5jb21lID09ICJNZWRpdW0iXSkNCnN1bW1hcnkoc3R1ZGVudF9kYXRhJEhvdXJzX1N0dWRpZWRbc3R1ZGVudF9kYXRhJEZhbWlseV9JbmNvbWUgPT0gIkhpZ2giXSkNCmBgYA0KDQpUaGUgc3VtbWFyeSBzdGF0aXN0aWNzIG9mIHRoZSBhdmVyYWdlIG51bWJlciBvZiBob3VycyBzdHVkZW50cyBzdHVkeSBwZXIgd2VlayBiYXNlZCBvbiBmYW1pbHkgaW5jb21lIGxldmVscyBzaG93IG5vIHNpZ25pZmljYW50IGRpZmZlcmVuY2VzLiBXZSB3aWxsIG5vdyB1c2UgQU5PVkEgdG8gdGVzdCBmb3IgZGlmZmVyZW5jZXMgaW4gc3R1ZHkgaG91cnMgYmFzZWQgb24gZmFtaWx5IGluY29tZSBsZXZlbHMuIEJ1dCBmaXJzdCwgd2UgbmVlZCB0byBjaGVjayB0aGUgYXNzdW1wdGlvbnMgb2YgQU5PVkEuDQoNCmBgYHtyfQ0KIyBTYW1wbGUgdGhlIGRhdGENCmxvd19mYW1pbHlfaW5jb21lIDwtIHN0dWRlbnRfZGF0YSRIb3Vyc19TdHVkaWVkW3N0dWRlbnRfZGF0YSRGYW1pbHlfSW5jb21lID09ICJMb3ciXVtzYW1wbGUoc3VtKHN0dWRlbnRfZGF0YSRGYW1pbHlfSW5jb21lID09ICJMb3ciKSwgMTAwKV0NCm1lZGl1bV9mYW1pbHlfaW5jb21lIDwtIHN0dWRlbnRfZGF0YSRIb3Vyc19TdHVkaWVkW3N0dWRlbnRfZGF0YSRGYW1pbHlfSW5jb21lID09ICJNZWRpdW0iXVtzYW1wbGUoc3VtKHN0dWRlbnRfZGF0YSRGYW1pbHlfSW5jb21lID09ICJNZWRpdW0iKSwgMTAwKV0NCmhpZ2hfZmFtaWx5X2luY29tZSA8LSBzdHVkZW50X2RhdGEkSG91cnNfU3R1ZGllZFtzdHVkZW50X2RhdGEkRmFtaWx5X0luY29tZSA9PSAiSGlnaCJdW3NhbXBsZShzdW0oc3R1ZGVudF9kYXRhJEZhbWlseV9JbmNvbWUgPT0gIkhpZ2giKSwgMTAwKV0NCg0KIyBIaXN0b2dyYW0gb2Ygc3R1ZHkgaG91cnMgYnkgZmFtaWx5IGluY29tZQ0KcGFyKG1mcm93ID0gYygxLCAzKSkNCmhpc3QobG93X2ZhbWlseV9pbmNvbWUsIG1haW4gPSAiTG93IEZhbWlseSBJbmNvbWUiLCB4bGFiID0gIlN0dWR5IEhvdXJzIiwgY29sID0gInNreWJsdWUiLCBib3JkZXIgPSAiYmxhY2siKQ0KaGlzdChtZWRpdW1fZmFtaWx5X2luY29tZSwgbWFpbiA9ICJNZWRpdW0gRmFtaWx5IEluY29tZSIsIHhsYWIgPSAiU3R1ZHkgSG91cnMiLCBjb2wgPSAic2t5Ymx1ZSIsIGJvcmRlciA9ICJibGFjayIpDQpoaXN0KGhpZ2hfZmFtaWx5X2luY29tZSwgbWFpbiA9ICJIaWdoIEZhbWlseSBJbmNvbWUiLCB4bGFiID0gIlN0dWR5IEhvdXJzIiwgY29sID0gInNreWJsdWUiLCBib3JkZXIgPSAiYmxhY2siKQ0KDQojIENoZWNrIGFzc3VtcHRpb25zIG9mIEFOT1ZBDQpzaGFwaXJvLnRlc3QobG93X2ZhbWlseV9pbmNvbWUpDQpzaGFwaXJvLnRlc3QobWVkaXVtX2ZhbWlseV9pbmNvbWUpDQpzaGFwaXJvLnRlc3QoaGlnaF9mYW1pbHlfaW5jb21lKQ0KYGBgDQoNCkJvdGggdGhlIGhpc3RvZ3JhbXMgYW5kIHRoZSBTaGFwaXJvLVdpbGsgdGVzdCBzaG93IHRoYXQgdGhlIGRpc3RyaWJ1dGlvbiBvZiBzdHVkeSBob3VycyBpcyBhcHByb3hpbWF0ZWx5IG5vcm1hbCBmb3IgYWxsIHN0dWRlbnRzLiBXZSB3aWxsIG5vdyB1c2UgQU5PVkEgdG8gdGVzdCBmb3IgZGlmZmVyZW5jZXMgaW4gc3R1ZHkgaG91cnMgYmFzZWQgb24gZmFtaWx5IGluY29tZSBsZXZlbHMuDQoNCmBgYHtyfQ0KIyBBTk9WQSB0ZXN0IGZvciBzdHVkeSBob3VycyBieSBmYW1pbHkgaW5jb21lDQphbm92YV9mYW1pbHlfaW5jb21lIDwtIGFvdihIb3Vyc19TdHVkaWVkIH4gRmFtaWx5X0luY29tZSwgZGF0YSA9IHN0dWRlbnRfZGF0YSkNCnN1bW1hcnkoYW5vdmFfZmFtaWx5X2luY29tZSkNCmBgYA0KDQpUaGUgQU5PVkEgdGVzdCBzaG93cyB0aGF0IHRoZXJlIGlzIG5vIHNpZ25pZmljYW50IGRpZmZlcmVuY2UgaW4gdGhlIGF2ZXJhZ2UgbnVtYmVyIG9mIGhvdXJzIHN0dWRlbnRzIHN0dWR5IHBlciB3ZWVrIGJhc2VkIG9uIGZhbWlseSBpbmNvbWUgbGV2ZWxzLCB3aXRoIGEgcC12YWx1ZSBncmVhdGVyIHRoYW4gMC4wNS4gVGhpcyBpbmRpY2F0ZXMgdGhhdCBmYW1pbHkgaW5jb21lIGRvZXMgbm90IGhhdmUgYSBzaWduaWZpY2FudCBpbXBhY3Qgb24gdGhlIG51bWJlciBvZiBob3VycyBzdHVkZW50cyBzdHVkeSBwZXIgd2Vlay4NCg0KIyMgQXZlcmFnZSBOdW1iZXIgb2YgSG91cnMgU3R1ZGVudHMgU3R1ZHkgcGVyIFdlZWsgKFRlYWNoZXIgUXVhbGl0eSBDYXRlZ29yeSkNCg0KTmV4dCwgd2UgZXhwbG9yZSB0aGUgYXZlcmFnZSBudW1iZXIgb2YgaG91cnMgc3R1ZGVudHMgc3R1ZHkgcGVyIHdlZWsgYmFzZWQgb24gdGVhY2hlciBxdWFsaXR5IGxldmVscy4NCg0KYGBge3J9DQojIFN1bW1hcnkgc3RhdGlzdGljcyBmb3Igc3R1ZHkgaG91cnMgYnkgdGVhY2hlciBxdWFsaXR5DQpzdW1tYXJ5KHN0dWRlbnRfZGF0YSRIb3Vyc19TdHVkaWVkW3N0dWRlbnRfZGF0YSRUZWFjaGVyX1F1YWxpdHkgPT0gIkxvdyJdKQ0Kc3VtbWFyeShzdHVkZW50X2RhdGEkSG91cnNfU3R1ZGllZFtzdHVkZW50X2RhdGEkVGVhY2hlcl9RdWFsaXR5ID09ICJNZWRpdW0iXSkNCnN1bW1hcnkoc3R1ZGVudF9kYXRhJEhvdXJzX1N0dWRpZWRbc3R1ZGVudF9kYXRhJFRlYWNoZXJfUXVhbGl0eSA9PSAiSGlnaCJdKQ0KYGBgDQoNClRoZSBzdW1tYXJ5IHN0YXRpc3RpY3Mgb2YgdGhlIGF2ZXJhZ2UgbnVtYmVyIG9mIGhvdXJzIHN0dWRlbnRzIHN0dWR5IHBlciB3ZWVrIGJhc2VkIG9uIHRlYWNoZXIgcXVhbGl0eSBsZXZlbHMgc2hvdyBubyBzaWduaWZpY2FudCBkaWZmZXJlbmNlcy4gV2Ugd2lsbCBub3cgdXNlIEFOT1ZBIHRvIHRlc3QgZm9yIGRpZmZlcmVuY2VzIGluIHN0dWR5IGhvdXJzIGJhc2VkIG9uIHRlYWNoZXIgcXVhbGl0eSBsZXZlbHMuIEJ1dCBmaXJzdCwgd2UgbmVlZCB0byBjaGVjayB0aGUgYXNzdW1wdGlvbnMgb2YgQU5PVkEuDQoNCmBgYHtyfQ0KIyBTYW1wbGUgdGhlIGRhdGENCmxvd190ZWFjaGVyX3F1YWxpdHkgPC0gc3R1ZGVudF9kYXRhJEhvdXJzX1N0dWRpZWRbc3R1ZGVudF9kYXRhJFRlYWNoZXJfUXVhbGl0eSA9PSAiTG93Il1bc2FtcGxlKHN1bShzdHVkZW50X2RhdGEkVGVhY2hlcl9RdWFsaXR5ID09ICJMb3ciKSwgMTAwKV0NCm1lZGl1bV90ZWFjaGVyX3F1YWxpdHkgPC0gc3R1ZGVudF9kYXRhJEhvdXJzX1N0dWRpZWRbc3R1ZGVudF9kYXRhJFRlYWNoZXJfUXVhbGl0eSA9PSAiTWVkaXVtIl1bc2FtcGxlKHN1bShzdHVkZW50X2RhdGEkVGVhY2hlcl9RdWFsaXR5ID09ICJNZWRpdW0iKSwgMTAwKV0NCmhpZ2hfdGVhY2hlcl9xdWFsaXR5IDwtIHN0dWRlbnRfZGF0YSRIb3Vyc19TdHVkaWVkW3N0dWRlbnRfZGF0YSRUZWFjaGVyX1F1YWxpdHkgPT0gIkhpZ2giXVtzYW1wbGUoc3VtKHN0dWRlbnRfZGF0YSRUZWFjaGVyX1F1YWxpdHkgPT0gIkhpZ2giKSwgMTAwKV0NCg0KIyBIaXN0b2dyYW0gb2Ygc3R1ZHkgaG91cnMgYnkgdGVhY2hlciBxdWFsaXR5DQpwYXIobWZyb3cgPSBjKDEsIDMpKQ0KaGlzdChsb3dfdGVhY2hlcl9xdWFsaXR5LCBtYWluID0gIkxvdyBUZWFjaGVyIFF1YWxpdHkiLCB4bGFiID0gIlN0dWR5IEhvdXJzIiwgY29sID0gInNreWJsdWUiLCBib3JkZXIgPSAiYmxhY2siKQ0KaGlzdChtZWRpdW1fdGVhY2hlcl9xdWFsaXR5LCBtYWluID0gIk1lZGl1bSBUZWFjaGVyIFF1YWxpdHkiLCB4bGFiID0gIlN0dWR5IEhvdXJzIiwgY29sID0gInNreWJsdWUiLCBib3JkZXIgPSAiYmxhY2siKQ0KaGlzdChoaWdoX3RlYWNoZXJfcXVhbGl0eSwgbWFpbiA9ICJIaWdoIFRlYWNoZXIgUXVhbGl0eSIsIHhsYWIgPSAiU3R1ZHkgSG91cnMiLCBjb2wgPSAic2t5Ymx1ZSIsIGJvcmRlciA9ICJibGFjayIpDQoNCiMgQ2hlY2sgYXNzdW1wdGlvbnMgb2YgQU5PVkENCnNoYXBpcm8udGVzdChsb3dfdGVhY2hlcl9xdWFsaXR5KQ0Kc2hhcGlyby50ZXN0KG1lZGl1bV90ZWFjaGVyX3F1YWxpdHkpDQpzaGFwaXJvLnRlc3QoaGlnaF90ZWFjaGVyX3F1YWxpdHkpDQpgYGANCg0KQWxsIHRocmVlIGhpc3RvZ3JhbXMgYW5kIHRoZSBTaGFwaXJvLVdpbGsgdGVzdCBzaG93IHRoYXQgdGhlIGRpc3RyaWJ1dGlvbiBvZiBzdHVkeSBob3VycyBpcyBhcHByb3hpbWF0ZWx5IG5vcm1hbCBmb3IgYWxsIHN0dWRlbnRzLiBXZSB3aWxsIG5vdyB1c2UgQU5PVkEgdG8gdGVzdCBmb3IgZGlmZmVyZW5jZXMgaW4gc3R1ZHkgaG91cnMgYmFzZWQgb24gdGVhY2hlciBxdWFsaXR5IGxldmVscy4NCg0KYGBge3J9DQojIEFOT1ZBIHRlc3QgZm9yIHN0dWR5IGhvdXJzIGJ5IHRlYWNoZXIgcXVhbGl0eQ0KYW5vdmFfdGVhY2hlcl9xdWFsaXR5IDwtIGFvdihIb3Vyc19TdHVkaWVkIH4gVGVhY2hlcl9RdWFsaXR5LCBkYXRhID0gc3R1ZGVudF9kYXRhKQ0Kc3VtbWFyeShhbm92YV90ZWFjaGVyX3F1YWxpdHkpDQpgYGANCg0KVGhlIEFOT1ZBIHRlc3Qgc2hvd3MgdGhhdCB0aGVyZSBpcyBubyBzaWduaWZpY2FudCBkaWZmZXJlbmNlIGluIHRoZSBhdmVyYWdlIG51bWJlciBvZiBob3VycyBzdHVkZW50cyBzdHVkeSBwZXIgd2VlayBiYXNlZCBvbiB0ZWFjaGVyIHF1YWxpdHkgbGV2ZWxzLCB3aXRoIGEgcC12YWx1ZSBncmVhdGVyIHRoYW4gMC4wNS4gVGhpcyBpbmRpY2F0ZXMgdGhhdCB0ZWFjaGVyIHF1YWxpdHkgZG9lcyBub3QgaGF2ZSBhIHNpZ25pZmljYW50IGltcGFjdCBvbiB0aGUgbnVtYmVyIG9mIGhvdXJzIHN0dWRlbnRzIHN0dWR5IHBlciB3ZWVrLg0KDQojIyBBdmVyYWdlIE51bWJlciBvZiBIb3VycyBTdHVkZW50cyBTdHVkeSBwZXIgV2VlayAoU2Nob29sIFR5cGUgQ2F0ZWdvcnkpDQoNCk5leHQsIHdlIGV4cGxvcmUgdGhlIGF2ZXJhZ2UgbnVtYmVyIG9mIGhvdXJzIHN0dWRlbnRzIHN0dWR5IHBlciB3ZWVrIGJhc2VkIG9uIHNjaG9vbCB0eXBlLg0KDQpgYGB7cn0NCiMgU3VtbWFyeSBzdGF0aXN0aWNzIGZvciBzdHVkeSBob3VycyBieSBzY2hvb2wgdHlwZQ0Kc3VtbWFyeShzdHVkZW50X2RhdGEkSG91cnNfU3R1ZGllZFtzdHVkZW50X2RhdGEkU2Nob29sX1R5cGUgPT0gIlB1YmxpYyJdKQ0Kc3VtbWFyeShzdHVkZW50X2RhdGEkSG91cnNfU3R1ZGllZFtzdHVkZW50X2RhdGEkU2Nob29sX1R5cGUgPT0gIlByaXZhdGUiXSkNCmBgYA0KDQpUaGUgc3VtbWFyeSBzdGF0aXN0aWNzIG9mIHRoZSBhdmVyYWdlIG51bWJlciBvZiBob3VycyBzdHVkZW50cyBzdHVkeSBwZXIgd2VlayBiYXNlZCBvbiBzY2hvb2wgdHlwZSBzaG93IG5vIHNpZ25pZmljYW50IGRpZmZlcmVuY2VzLiBXZSB3aWxsIG5vdyB1c2UgdC10ZXN0IHRvIHRlc3QgZm9yIGRpZmZlcmVuY2VzIGluIHN0dWR5IGhvdXJzIGJhc2VkIG9uIHNjaG9vbCB0eXBlLiBCdXQgZmlyc3QsIHdlIG5lZWQgdG8gY2hlY2sgdGhlIGFzc3VtcHRpb25zIG9mIHQtdGVzdC4NCg0KYGBge3J9DQojIFNhbXBsZSB0aGUgZGF0YQ0KcHVibGljX3NjaG9vbCA8LSBzdHVkZW50X2RhdGEkSG91cnNfU3R1ZGllZFtzdHVkZW50X2RhdGEkU2Nob29sX1R5cGUgPT0gIlB1YmxpYyJdW3NhbXBsZShzdW0oc3R1ZGVudF9kYXRhJFNjaG9vbF9UeXBlID09ICJQdWJsaWMiKSwgMTAwKV0NCnByaXZhdGVfc2Nob29sIDwtIHN0dWRlbnRfZGF0YSRIb3Vyc19TdHVkaWVkW3N0dWRlbnRfZGF0YSRTY2hvb2xfVHlwZSA9PSAiUHJpdmF0ZSJdW3NhbXBsZShzdW0oc3R1ZGVudF9kYXRhJFNjaG9vbF9UeXBlID09ICJQcml2YXRlIiksIDEwMCldDQoNCiMgSGlzdG9ncmFtIG9mIHN0dWR5IGhvdXJzIGJ5IHNjaG9vbCB0eXBlDQpwYXIobWZyb3cgPSBjKDEsIDIpKQ0KaGlzdChwdWJsaWNfc2Nob29sLCBtYWluID0gIlB1YmxpYyBTY2hvb2wiLCB4bGFiID0gIlN0dWR5IEhvdXJzIiwgY29sID0gInNreWJsdWUiLCBib3JkZXIgPSAiYmxhY2siKQ0KaGlzdChwcml2YXRlX3NjaG9vbCwgbWFpbiA9ICJQcml2YXRlIFNjaG9vbCIsIHhsYWIgPSAiU3R1ZHkgSG91cnMiLCBjb2wgPSAic2t5Ymx1ZSIsIGJvcmRlciA9ICJibGFjayIpDQoNCiMgQ2hlY2sgYXNzdW1wdGlvbnMgb2YgdC10ZXN0DQpzaGFwaXJvLnRlc3QocHVibGljX3NjaG9vbCkNCnNoYXBpcm8udGVzdChwcml2YXRlX3NjaG9vbCkNCmBgYA0KDQpCb3RoIGhpc3RvZ3JhbXMgYW5kIHRoZSBTaGFwaXJvLVdpbGsgdGVzdCBzaG93IHRoYXQgdGhlIGRpc3RyaWJ1dGlvbiBvZiBzdHVkeSBob3VycyBpcyBhcHByb3hpbWF0ZWx5IG5vcm1hbCBmb3IgYWxsIHN0dWRlbnRzLiBXZSB3aWxsIG5vdyB1c2UgdC10ZXN0IHRvIHRlc3QgZm9yIGRpZmZlcmVuY2VzIGluIHN0dWR5IGhvdXJzIGJhc2VkIG9uIHNjaG9vbCB0eXBlLg0KDQpgYGB7cn0NCiMgdC10ZXN0IHRlc3QgZm9yIHN0dWR5IGhvdXJzIGJ5IHNjaG9vbCB0eXBlDQp0LnRlc3QocHVibGljX3NjaG9vbCwgcHJpdmF0ZV9zY2hvb2wpDQpgYGANCg0KVGhlIHQtdGVzdCB0ZXN0IHNob3dzIHRoYXQgdGhlcmUgaXMgbm8gc2lnbmlmaWNhbnQgZGlmZmVyZW5jZSBpbiB0aGUgYXZlcmFnZSBudW1iZXIgb2YgaG91cnMgc3R1ZGVudHMgc3R1ZHkgcGVyIHdlZWsgYmFzZWQgb24gc2Nob29sIHR5cGUsIHdpdGggYSBwLXZhbHVlIGdyZWF0ZXIgdGhhbiAwLjA1LiBUaGlzIGluZGljYXRlcyB0aGF0IHNjaG9vbCB0eXBlIGRvZXMgbm90IGhhdmUgYSBzaWduaWZpY2FudCBpbXBhY3Qgb24gdGhlIG51bWJlciBvZiBob3VycyBzdHVkZW50cyBzdHVkeSBwZXIgd2Vlay4NCg0KIyMgQXZlcmFnZSBOdW1iZXIgb2YgSG91cnMgU3R1ZGVudHMgU3R1ZHkgcGVyIFdlZWsgKFBlZXIgSW5mbHVlbmNlIENhdGVnb3J5KQ0KDQpOZXh0LCB3ZSBleHBsb3JlIHRoZSBhdmVyYWdlIG51bWJlciBvZiBob3VycyBzdHVkZW50cyBzdHVkeSBwZXIgd2VlayBiYXNlZCBvbiBwZWVyIGluZmx1ZW5jZSBsZXZlbHMuDQoNCmBgYHtyfQ0KIyBTdW1tYXJ5IHN0YXRpc3RpY3MgZm9yIHN0dWR5IGhvdXJzIGJ5IHBlZXIgaW5mbHVlbmNlDQpzdW1tYXJ5KHN0dWRlbnRfZGF0YSRIb3Vyc19TdHVkaWVkW3N0dWRlbnRfZGF0YSRQZWVyX0luZmx1ZW5jZSA9PSAiUG9zaXRpdmUiXSkNCnN1bW1hcnkoc3R1ZGVudF9kYXRhJEhvdXJzX1N0dWRpZWRbc3R1ZGVudF9kYXRhJFBlZXJfSW5mbHVlbmNlID09ICJOZWdhdGl2ZSJdKQ0Kc3VtbWFyeShzdHVkZW50X2RhdGEkSG91cnNfU3R1ZGllZFtzdHVkZW50X2RhdGEkUGVlcl9JbmZsdWVuY2UgPT0gIk5ldXRyYWwiXSkNCmBgYA0KDQpUaGUgc3VtbWFyeSBzdGF0aXN0aWNzIG9mIHRoZSBhdmVyYWdlIG51bWJlciBvZiBob3VycyBzdHVkZW50cyBzdHVkeSBwZXIgd2VlayBiYXNlZCBvbiBwZWVyIGluZmx1ZW5jZSBsZXZlbHMgc2hvdyBubyBzaWduaWZpY2FudCBkaWZmZXJlbmNlcy4gV2Ugd2lsbCBub3cgdXNlIEFOT1ZBIHRvIHRlc3QgZm9yIGRpZmZlcmVuY2VzIGluIHN0dWR5IGhvdXJzIGJhc2VkIG9uIHBlZXIgaW5mbHVlbmNlIGxldmVscy4gQnV0IGZpcnN0LCB3ZSBuZWVkIHRvIGNoZWNrIHRoZSBhc3N1bXB0aW9ucyBvZiBBTk9WQS4NCg0KYGBge3J9DQojIFNhbXBsZSB0aGUgZGF0YQ0KcG9zaXRpdmVfcGVlcl9pbmZsdWVuY2UgPC0gc3R1ZGVudF9kYXRhJEhvdXJzX1N0dWRpZWRbc3R1ZGVudF9kYXRhJFBlZXJfSW5mbHVlbmNlID09ICJQb3NpdGl2ZSJdW3NhbXBsZShzdW0oc3R1ZGVudF9kYXRhJFBlZXJfSW5mbHVlbmNlID09ICJQb3NpdGl2ZSIpLCAxMDApXQ0KbmVnYXRpdmVfcGVlcl9pbmZsdWVuY2UgPC0gc3R1ZGVudF9kYXRhJEhvdXJzX1N0dWRpZWRbc3R1ZGVudF9kYXRhJFBlZXJfSW5mbHVlbmNlID09ICJOZWdhdGl2ZSJdW3NhbXBsZShzdW0oc3R1ZGVudF9kYXRhJFBlZXJfSW5mbHVlbmNlID09ICJOZWdhdGl2ZSIpLCAxMDApXQ0KbmV1dHJhbF9wZWVyX2luZmx1ZW5jZSA8LSBzdHVkZW50X2RhdGEkSG91cnNfU3R1ZGllZFtzdHVkZW50X2RhdGEkUGVlcl9JbmZsdWVuY2UgPT0gIk5ldXRyYWwiXVtzYW1wbGUoc3VtKHN0dWRlbnRfZGF0YSRQZWVyX0luZmx1ZW5jZSA9PSAiTmV1dHJhbCIpLCAxMDApXQ0KDQojIEhpc3RvZ3JhbSBvZiBzdHVkeSBob3VycyBieSBwZWVyIGluZmx1ZW5jZQ0KcGFyKG1mcm93ID0gYygxLCAzKSkNCmhpc3QocG9zaXRpdmVfcGVlcl9pbmZsdWVuY2UsIG1haW4gPSAiUG9zaXRpdmUgUGVlciBJbmZsdWVuY2UiLCB4bGFiID0gIlN0dWR5IEhvdXJzIiwgY29sID0gInNreWJsdWUiLCBib3JkZXIgPSAiYmxhY2siKQ0KaGlzdChuZWdhdGl2ZV9wZWVyX2luZmx1ZW5jZSwgbWFpbiA9ICJOZWdhdGl2ZSBQZWVyIEluZmx1ZW5jZSIsIHhsYWIgPSAiU3R1ZHkgSG91cnMiLCBjb2wgPSAic2t5Ymx1ZSIsIGJvcmRlciA9ICJibGFjayIpDQpoaXN0KG5ldXRyYWxfcGVlcl9pbmZsdWVuY2UsIG1haW4gPSAiTmV1dHJhbCBQZWVyIEluZmx1ZW5jZSIsIHhsYWIgPSAiU3R1ZHkgSG91cnMiLCBjb2wgPSAic2t5Ymx1ZSIsIGJvcmRlciA9ICJibGFjayIpDQoNCiMgQ2hlY2sgYXNzdW1wdGlvbnMgb2YgQU5PVkENCnNoYXBpcm8udGVzdChwb3NpdGl2ZV9wZWVyX2luZmx1ZW5jZSkNCnNoYXBpcm8udGVzdChuZWdhdGl2ZV9wZWVyX2luZmx1ZW5jZSkNCnNoYXBpcm8udGVzdChuZXV0cmFsX3BlZXJfaW5mbHVlbmNlKQ0KYGBgDQoNCkFsbCB0aHJlZSBoaXN0b2dyYW1zIGFuZCB0aGUgU2hhcGlyby1XaWxrIHRlc3Qgc2hvdyB0aGF0IHRoZSBkaXN0cmlidXRpb24gb2Ygc3R1ZHkgaG91cnMgaXMgYXBwcm94aW1hdGVseSBub3JtYWwgZm9yIGFsbCBzdHVkZW50cy4gV2Ugd2lsbCBub3cgdXNlIEFOT1ZBIHRvIHRlc3QgZm9yIGRpZmZlcmVuY2VzIGluIHN0dWR5IGhvdXJzIGJhc2VkIG9uIHBlZXIgaW5mbHVlbmNlIGxldmVscy4NCg0KYGBge3J9DQojIEFOT1ZBIHRlc3QgZm9yIHN0dWR5IGhvdXJzIGJ5IHBlZXIgaW5mbHVlbmNlDQphbm92YV9wZWVyX2luZmx1ZW5jZSA8LSBhb3YoSG91cnNfU3R1ZGllZCB+IFBlZXJfSW5mbHVlbmNlLCBkYXRhID0gc3R1ZGVudF9kYXRhKQ0Kc3VtbWFyeShhbm92YV9wZWVyX2luZmx1ZW5jZSkNCmBgYA0KDQpUaGUgQU5PVkEgdGVzdCBzaG93cyB0aGF0IHRoZXJlIGlzIG5vIHNpZ25pZmljYW50IGRpZmZlcmVuY2UgaW4gdGhlIGF2ZXJhZ2UgbnVtYmVyIG9mIGhvdXJzIHN0dWRlbnRzIHN0dWR5IHBlciB3ZWVrIGJhc2VkIG9uIHBlZXIgaW5mbHVlbmNlIGxldmVscywgd2l0aCBhIHAtdmFsdWUgZ3JlYXRlciB0aGFuIDAuMDUuIFRoaXMgaW5kaWNhdGVzIHRoYXQgcGVlciBpbmZsdWVuY2UgZG9lcyBub3QgaGF2ZSBhIHNpZ25pZmljYW50IGltcGFjdCBvbiB0aGUgbnVtYmVyIG9mIGhvdXJzIHN0dWRlbnRzIHN0dWR5IHBlciB3ZWVrLg0KDQojIyBBdmVyYWdlIE51bWJlciBvZiBIb3VycyBTdHVkZW50cyBTdHVkeSBwZXIgV2VlayAoTGVhcm5pbmcgRGlzYWJpbGl0eSBDYXRlZ29yeSkNCg0KTmV4dCwgd2UgZXhwbG9yZSB0aGUgYXZlcmFnZSBudW1iZXIgb2YgaG91cnMgc3R1ZGVudHMgc3R1ZHkgcGVyIHdlZWsgYmFzZWQgb24gbGVhcm5pbmcgZGlzYWJpbGl0eS4NCg0KYGBge3J9DQojIFN1bW1hcnkgc3RhdGlzdGljcyBmb3Igc3R1ZHkgaG91cnMgYnkgbGVhcm5pbmcgZGlzYWJpbGl0eQ0Kc3VtbWFyeShzdHVkZW50X2RhdGEkSG91cnNfU3R1ZGllZFtzdHVkZW50X2RhdGEkTGVhcm5pbmdfRGlzYWJpbGl0aWVzID09ICJZZXMiXSkNCnN1bW1hcnkoc3R1ZGVudF9kYXRhJEhvdXJzX1N0dWRpZWRbc3R1ZGVudF9kYXRhJExlYXJuaW5nX0Rpc2FiaWxpdGllcyA9PSAiTm8iXSkNCmBgYA0KDQpUaGUgc3VtbWFyeSBzdGF0aXN0aWNzIG9mIHRoZSBhdmVyYWdlIG51bWJlciBvZiBob3VycyBzdHVkZW50cyBzdHVkeSBwZXIgd2VlayBiYXNlZCBvbiBsZWFybmluZyBkaXNhYmlsaXR5IHNob3cgbm8gc2lnbmlmaWNhbnQgZGlmZmVyZW5jZXMuIFdlIHdpbGwgbm93IHVzZSB0LXRlc3QgdG8gdGVzdCBmb3IgZGlmZmVyZW5jZXMgaW4gc3R1ZHkgaG91cnMgYmFzZWQgb24gbGVhcm5pbmcgZGlzYWJpbGl0eS4gQnV0IGZpcnN0LCB3ZSBuZWVkIHRvIGNoZWNrIHRoZSBhc3N1bXB0aW9ucyBvZiB0LXRlc3QuDQoNCmBgYHtyfQ0KIyBTYW1wbGUgdGhlIGRhdGENCmxlYXJuaW5nX2Rpc2FiaWxpdGllcyA8LSBzdHVkZW50X2RhdGEkSG91cnNfU3R1ZGllZFtzdHVkZW50X2RhdGEkTGVhcm5pbmdfRGlzYWJpbGl0aWVzID09ICJZZXMiXVtzYW1wbGUoc3VtKHN0dWRlbnRfZGF0YSRMZWFybmluZ19EaXNhYmlsaXRpZXMgPT0gIlllcyIpLCAxMDApXQ0Kbm9fbGVhcm5pbmdfZGlzYWJpbGl0aWVzIDwtIHN0dWRlbnRfZGF0YSRIb3Vyc19TdHVkaWVkW3N0dWRlbnRfZGF0YSRMZWFybmluZ19EaXNhYmlsaXRpZXMgPT0gIk5vIl1bc2FtcGxlKHN1bShzdHVkZW50X2RhdGEkTGVhcm5pbmdfRGlzYWJpbGl0aWVzID09ICJObyIpLCAxMDApXQ0KDQojIEhpc3RvZ3JhbSBvZiBzdHVkeSBob3VycyBieSBsZWFybmluZyBkaXNhYmlsaXR5DQpwYXIobWZyb3cgPSBjKDEsIDIpKQ0KaGlzdChsZWFybmluZ19kaXNhYmlsaXRpZXMsIG1haW4gPSAiTGVhcm5pbmcgRGlzYWJpbGl0aWVzIiwgeGxhYiA9ICJTdHVkeSBIb3VycyIsIGNvbCA9ICJza3libHVlIiwgYm9yZGVyID0gImJsYWNrIikNCmhpc3Qobm9fbGVhcm5pbmdfZGlzYWJpbGl0aWVzLCBtYWluID0gIk5vIExlYXJuaW5nIERpc2FiaWxpdGllcyIsIHhsYWIgPSAiU3R1ZHkgSG91cnMiLCBjb2wgPSAic2t5Ymx1ZSIsIGJvcmRlciA9ICJibGFjayIpDQoNCiMgQ2hlY2sgYXNzdW1wdGlvbnMgb2YgdC10ZXN0DQpzaGFwaXJvLnRlc3QobGVhcm5pbmdfZGlzYWJpbGl0aWVzKQ0Kc2hhcGlyby50ZXN0KG5vX2xlYXJuaW5nX2Rpc2FiaWxpdGllcykNCmBgYA0KDQpUaGUgU2hhcGlyby1XaWxrIHRlc3Qgc2hvd3MgdGhhdCB0aGUgZGlzdHJpYnV0aW9uIG9mIHN0dWR5IGhvdXJzIGlzIGFwcHJveGltYXRlbHkgbm9ybWFsIGZvciBzdHVkZW50cyB3aXRoIGxlYXJuaW5nIGRpc2FiaWxpdGllcywgd2l0aCBhIHAtdmFsdWUgZ3JlYXRlciB0aGFuIDAuMDUuIEhvd2V2ZXIsIHRoZSBkaXN0cmlidXRpb24gZm9yIHN0dWRlbnRzIHdpdGhvdXQgbGVhcm5pbmcgZGlzYWJpbGl0aWVzIGlzIHNsaWdodGx5IHNrZXdlZCwgd2l0aCBhIHAtdmFsdWUgbGVzcyB0aGFuIDAuMDUuIFdlIHdpbGwgbm93IHVzZSB3aWxjb3hvbiByYW5rIHN1bSB0ZXN0IHRvIHRlc3QgZm9yIGRpZmZlcmVuY2VzIGluIHN0dWR5IGhvdXJzIGJhc2VkIG9uIGxlYXJuaW5nIGRpc2FiaWxpdHkuDQoNCmBgYHtyfQ0KIyBXaWxjb3hvbiByYW5rIHN1bSB0ZXN0IGZvciBzdHVkeSBob3VycyBieSBsZWFybmluZyBkaXNhYmlsaXR5DQp3aWxjb3gudGVzdChsZWFybmluZ19kaXNhYmlsaXRpZXMsIG5vX2xlYXJuaW5nX2Rpc2FiaWxpdGllcykNCmBgYA0KDQpUaGUgdC10ZXN0IHRlc3Qgc2hvd3MgdGhhdCB0aGVyZSBpcyBubyBzaWduaWZpY2FudCBkaWZmZXJlbmNlIGluIHRoZSBhdmVyYWdlIG51bWJlciBvZiBob3VycyBzdHVkZW50cyBzdHVkeSBwZXIgd2VlayBiYXNlZCBvbiBsZWFybmluZyBkaXNhYmlsaXR5LCB3aXRoIGEgcC12YWx1ZSBncmVhdGVyIHRoYW4gMC4wNS4gVGhpcyBpbmRpY2F0ZXMgdGhhdCBsZWFybmluZyBkaXNhYmlsaXRpZXMgZG8gbm90IGhhdmUgYSBzaWduaWZpY2FudCBpbXBhY3Qgb24gdGhlIG51bWJlciBvZiBob3VycyBzdHVkZW50cyBzdHVkeSBwZXIgd2Vlay4NCg0KIyMgQXZlcmFnZSBOdW1iZXIgb2YgSG91cnMgU3R1ZGVudHMgU3R1ZHkgcGVyIFdlZWsgKFBhcmVudGFsIEVkdWNhdGlvbiBMZXZlbCBDYXRlZ29yeSkNCg0KTmV4dCwgd2UgZXhwbG9yZSB0aGUgYXZlcmFnZSBudW1iZXIgb2YgaG91cnMgc3R1ZGVudHMgc3R1ZHkgcGVyIHdlZWsgYmFzZWQgb24gcGFyZW50YWwgZWR1Y2F0aW9uIGxldmVscy4NCg0KYGBge3J9DQojIFN1bW1hcnkgc3RhdGlzdGljcyBmb3Igc3R1ZHkgaG91cnMgYnkgcGFyZW50YWwgZWR1Y2F0aW9uIGxldmVsDQpzdW1tYXJ5KHN0dWRlbnRfZGF0YSRIb3Vyc19TdHVkaWVkW3N0dWRlbnRfZGF0YSRQYXJlbnRhbF9FZHVjYXRpb25fTGV2ZWwgPT0gIkhpZ2ggU2Nob29sIl0pDQpzdW1tYXJ5KHN0dWRlbnRfZGF0YSRIb3Vyc19TdHVkaWVkW3N0dWRlbnRfZGF0YSRQYXJlbnRhbF9FZHVjYXRpb25fTGV2ZWwgPT0gIkNvbGxlZ2UiXSkNCnN1bW1hcnkoc3R1ZGVudF9kYXRhJEhvdXJzX1N0dWRpZWRbc3R1ZGVudF9kYXRhJFBhcmVudGFsX0VkdWNhdGlvbl9MZXZlbCA9PSAiUG9zdGdyYWR1YXRlIl0pDQpgYGANCg0KVGhlIHN1bW1hcnkgc3RhdGlzdGljcyBvZiB0aGUgYXZlcmFnZSBudW1iZXIgb2YgaG91cnMgc3R1ZGVudHMgc3R1ZHkgcGVyIHdlZWsgYmFzZWQgb24gcGFyZW50YWwgZWR1Y2F0aW9uIGxldmVscyBzaG93IG5vIHNpZ25pZmljYW50IGRpZmZlcmVuY2VzLiBXZSB3aWxsIG5vdyB1c2UgQU5PVkEgdG8gdGVzdCBmb3IgZGlmZmVyZW5jZXMgaW4gc3R1ZHkgaG91cnMgYmFzZWQgb24gcGFyZW50YWwgZWR1Y2F0aW9uIGxldmVscy4gQnV0IGZpcnN0LCB3ZSBuZWVkIHRvIGNoZWNrIHRoZSBhc3N1bXB0aW9ucyBvZiBBTk9WQS4NCg0KYGBge3J9DQojIFNhbXBsZSB0aGUgZGF0YQ0KaGlnaF9zY2hvb2xfZWR1Y2F0aW9uIDwtIHN0dWRlbnRfZGF0YSRIb3Vyc19TdHVkaWVkW3N0dWRlbnRfZGF0YSRQYXJlbnRhbF9FZHVjYXRpb25fTGV2ZWwgPT0gIkhpZ2ggU2Nob29sIl1bc2FtcGxlKHN1bShzdHVkZW50X2RhdGEkUGFyZW50YWxfRWR1Y2F0aW9uX0xldmVsID09ICJIaWdoIFNjaG9vbCIpLCAxMDApXQ0KY29sbGVnZV9lZHVjYXRpb24gPC0gc3R1ZGVudF9kYXRhJEhvdXJzX1N0dWRpZWRbc3R1ZGVudF9kYXRhJFBhcmVudGFsX0VkdWNhdGlvbl9MZXZlbCA9PSAiQ29sbGVnZSJdW3NhbXBsZShzdW0oc3R1ZGVudF9kYXRhJFBhcmVudGFsX0VkdWNhdGlvbl9MZXZlbCA9PSAiQ29sbGVnZSIpLCAxMDApXQ0KcG9zdGdyYWR1YXRlX2VkdWNhdGlvbiA8LSBzdHVkZW50X2RhdGEkSG91cnNfU3R1ZGllZFtzdHVkZW50X2RhdGEkUGFyZW50YWxfRWR1Y2F0aW9uX0xldmVsID09ICJQb3N0Z3JhZHVhdGUiXVtzYW1wbGUoc3VtKHN0dWRlbnRfZGF0YSRQYXJlbnRhbF9FZHVjYXRpb25fTGV2ZWwgPT0gIlBvc3RncmFkdWF0ZSIpLCAxMDApXQ0KDQojIEhpc3RvZ3JhbSBvZiBzdHVkeSBob3VycyBieSBwYXJlbnRhbCBlZHVjYXRpb24gbGV2ZWwNCnBhcihtZnJvdyA9IGMoMSwgMykpDQpoaXN0KGhpZ2hfc2Nob29sX2VkdWNhdGlvbiwgbWFpbiA9ICJIaWdoIFNjaG9vbCBFZHVjYXRpb24iLCB4bGFiID0gIlN0dWR5IEhvdXJzIiwgY29sID0gInNreWJsdWUiLCBib3JkZXIgPSAiYmxhY2siKQ0KaGlzdChjb2xsZWdlX2VkdWNhdGlvbiwgbWFpbiA9ICJDb2xsZWdlIEVkdWNhdGlvbiIsIHhsYWIgPSAiU3R1ZHkgSG91cnMiLCBjb2wgPSAic2t5Ymx1ZSIsIGJvcmRlciA9ICJibGFjayIpDQpoaXN0KHBvc3RncmFkdWF0ZV9lZHVjYXRpb24sIG1haW4gPSAiUG9zdGdyYWR1YXRlIEVkdWNhdGlvbiIsIHhsYWIgPSAiU3R1ZHkgSG91cnMiLCBjb2wgPSAic2t5Ymx1ZSIsIGJvcmRlciA9ICJibGFjayIpDQoNCiMgQ2hlY2sgYXNzdW1wdGlvbnMgb2YgQU5PVkENCnNoYXBpcm8udGVzdChoaWdoX3NjaG9vbF9lZHVjYXRpb24pDQpzaGFwaXJvLnRlc3QoY29sbGVnZV9lZHVjYXRpb24pDQpzaGFwaXJvLnRlc3QocG9zdGdyYWR1YXRlX2VkdWNhdGlvbikNCmBgYA0KDQpBbGwgdGhyZWUgaGlzdG9ncmFtcyBhbmQgdGhlIFNoYXBpcm8tV2lsayB0ZXN0IHNob3cgdGhhdCB0aGUgZGlzdHJpYnV0aW9uIG9mIHN0dWR5IGhvdXJzIGlzIGFwcHJveGltYXRlbHkgbm9ybWFsIGZvciBhbGwgc3R1ZGVudHMuIFdlIHdpbGwgbm93IHVzZSBBTk9WQSB0byB0ZXN0IGZvciBkaWZmZXJlbmNlcyBpbiBzdHVkeSBob3VycyBiYXNlZCBvbiBwYXJlbnRhbCBlZHVjYXRpb24gbGV2ZWxzLg0KDQpgYGB7cn0NCiMgQU5PVkEgdGVzdCBmb3Igc3R1ZHkgaG91cnMgYnkgcGFyZW50YWwgZWR1Y2F0aW9uIGxldmVsDQphbm92YV9wYXJlbnRhbF9lZHVjYXRpb25fbGV2ZWwgPC0gYW92KEhvdXJzX1N0dWRpZWQgfiBQYXJlbnRhbF9FZHVjYXRpb25fTGV2ZWwsIGRhdGEgPSBzdHVkZW50X2RhdGEpDQpzdW1tYXJ5KGFub3ZhX3BhcmVudGFsX2VkdWNhdGlvbl9sZXZlbCkNCmBgYA0KDQpUaGUgQU5PVkEgdGVzdCBzaG93cyB0aGF0IHRoZXJlIGlzIG5vIHNpZ25pZmljYW50IGRpZmZlcmVuY2UgaW4gdGhlIGF2ZXJhZ2UgbnVtYmVyIG9mIGhvdXJzIHN0dWRlbnRzIHN0dWR5IHBlciB3ZWVrIGJhc2VkIG9uIHBhcmVudGFsIGVkdWNhdGlvbiBsZXZlbHMsIHdpdGggYSBwLXZhbHVlIGdyZWF0ZXIgdGhhbiAwLjA1LiBUaGlzIGluZGljYXRlcyB0aGF0IHBhcmVudGFsIGVkdWNhdGlvbiBsZXZlbHMgZG8gbm90IGhhdmUgYSBzaWduaWZpY2FudCBpbXBhY3Qgb24gdGhlIG51bWJlciBvZiBob3VycyBzdHVkZW50cyBzdHVkeSBwZXIgd2Vlay4NCg0KIyMgQXZlcmFnZSBOdW1iZXIgb2YgSG91cnMgU3R1ZGVudHMgU3R1ZHkgcGVyIFdlZWsgKERpc3RhbmNlIGZyb20gSG9tZSBDYXRlZ29yeSkNCg0KTmV4dCwgd2UgZXhwbG9yZSB0aGUgYXZlcmFnZSBudW1iZXIgb2YgaG91cnMgc3R1ZGVudHMgc3R1ZHkgcGVyIHdlZWsgYmFzZWQgb24gdGhlIGRpc3RhbmNlIGZyb20gaG9tZSB0byBzY2hvb2wuDQoNCmBgYHtyfQ0KIyBTdW1tYXJ5IHN0YXRpc3RpY3MgZm9yIHN0dWR5IGhvdXJzIGJ5IGRpc3RhbmNlIGZyb20gaG9tZSAoTmVhciwgTW9kZXJhdGUsIEZhcg0Kc3VtbWFyeShzdHVkZW50X2RhdGEkSG91cnNfU3R1ZGllZFtzdHVkZW50X2RhdGEkRGlzdGFuY2VfZnJvbV9Ib21lID09ICJOZWFyIl0pDQpzdW1tYXJ5KHN0dWRlbnRfZGF0YSRIb3Vyc19TdHVkaWVkW3N0dWRlbnRfZGF0YSREaXN0YW5jZV9mcm9tX0hvbWUgPT0gIk1vZGVyYXRlIl0pDQpzdW1tYXJ5KHN0dWRlbnRfZGF0YSRIb3Vyc19TdHVkaWVkW3N0dWRlbnRfZGF0YSREaXN0YW5jZV9mcm9tX0hvbWUgPT0gIkZhciJdKQ0KYGBgDQoNClRoZSBzdW1tYXJ5IHN0YXRpc3RpY3Mgb2YgdGhlIGF2ZXJhZ2UgbnVtYmVyIG9mIGhvdXJzIHN0dWRlbnRzIHN0dWR5IHBlciB3ZWVrIGJhc2VkIG9uIHRoZSBkaXN0YW5jZSBmcm9tIGhvbWUgdG8gc2Nob29sIHNob3cgbm8gc2lnbmlmaWNhbnQgZGlmZmVyZW5jZXMuIFdlIHdpbGwgbm93IHVzZSBBTk9WQSB0byB0ZXN0IGZvciBkaWZmZXJlbmNlcyBpbiBzdHVkeSBob3VycyBiYXNlZCBvbiB0aGUgZGlzdGFuY2UgZnJvbSBob21lIHRvIHNjaG9vbC4gQnV0IGZpcnN0LCB3ZSBuZWVkIHRvIGNoZWNrIHRoZSBhc3N1bXB0aW9ucyBvZiBBTk9WQS4NCg0KYGBge3J9DQojIFNhbXBsZSB0aGUgZGF0YQ0KbmVhcl9kaXN0YW5jZSA8LSBzdHVkZW50X2RhdGEkSG91cnNfU3R1ZGllZFtzdHVkZW50X2RhdGEkRGlzdGFuY2VfZnJvbV9Ib21lID09ICJOZWFyIl1bc2FtcGxlKHN1bShzdHVkZW50X2RhdGEkRGlzdGFuY2VfZnJvbV9Ib21lID09ICJOZWFyIiksIDEwMCldDQptb2RlcmF0ZV9kaXN0YW5jZSA8LSBzdHVkZW50X2RhdGEkSG91cnNfU3R1ZGllZFtzdHVkZW50X2RhdGEkRGlzdGFuY2VfZnJvbV9Ib21lID09ICJNb2RlcmF0ZSJdW3NhbXBsZShzdW0oc3R1ZGVudF9kYXRhJERpc3RhbmNlX2Zyb21fSG9tZSA9PSAiTW9kZXJhdGUiKSwgMTAwKV0NCmZhcl9kaXN0YW5jZSA8LSBzdHVkZW50X2RhdGEkSG91cnNfU3R1ZGllZFtzdHVkZW50X2RhdGEkRGlzdGFuY2VfZnJvbV9Ib21lID09ICJGYXIiXVtzYW1wbGUoc3VtKHN0dWRlbnRfZGF0YSREaXN0YW5jZV9mcm9tX0hvbWUgPT0gIkZhciIpLCAxMDApXQ0KDQojIEhpc3RvZ3JhbSBvZiBzdHVkeSBob3VycyBieSBkaXN0YW5jZSBmcm9tIGhvbWUNCnBhcihtZnJvdyA9IGMoMSwgMykpDQpoaXN0KG5lYXJfZGlzdGFuY2UsIG1haW4gPSAiTmVhciBEaXN0YW5jZSBmcm9tIEhvbWUiLCB4bGFiID0gIlN0dWR5IEhvdXJzIiwgY29sID0gInNreWJsdWUiLCBib3JkZXIgPSAiYmxhY2siKQ0KaGlzdChtb2RlcmF0ZV9kaXN0YW5jZSwgbWFpbiA9ICJNb2RlcmF0ZSBEaXN0YW5jZSBmcm9tIEhvbWUiLCB4bGFiID0gIlN0dWR5IEhvdXJzIiwgY29sID0gInNreWJsdWUiLCBib3JkZXIgPSAiYmxhY2siKQ0KaGlzdChmYXJfZGlzdGFuY2UsIG1haW4gPSAiRmFyIERpc3RhbmNlIGZyb20gSG9tZSIsIHhsYWIgPSAiU3R1ZHkgSG91cnMiLCBjb2wgPSAic2t5Ymx1ZSIsIGJvcmRlciA9ICJibGFjayIpDQoNCiMgQ2hlY2sgYXNzdW1wdGlvbnMgb2YgQU5PVkENCnNoYXBpcm8udGVzdChuZWFyX2Rpc3RhbmNlKQ0Kc2hhcGlyby50ZXN0KG1vZGVyYXRlX2Rpc3RhbmNlKQ0Kc2hhcGlyby50ZXN0KGZhcl9kaXN0YW5jZSkNCmBgYA0KDQpBbGwgdGhyZWUgaGlzdG9ncmFtcyBhbmQgdGhlIFNoYXBpcm8tV2lsayB0ZXN0IHNob3cgdGhhdCB0aGUgZGlzdHJpYnV0aW9uIG9mIHN0dWR5IGhvdXJzIGlzIGFwcHJveGltYXRlbHkgbm9ybWFsIGZvciBhbGwgc3R1ZGVudHMuIFdlIHdpbGwgbm93IHVzZSBBTk9WQSB0byB0ZXN0IGZvciBkaWZmZXJlbmNlcyBpbiBzdHVkeSBob3VycyBiYXNlZCBvbiB0aGUgZGlzdGFuY2UgZnJvbSBob21lIHRvIHNjaG9vbC4NCg0KYGBge3J9DQojIEFOT1ZBIHRlc3QgZm9yIHN0dWR5IGhvdXJzIGJ5IGRpc3RhbmNlIGZyb20gaG9tZQ0KYW5vdmFfZGlzdGFuY2VfZnJvbV9ob21lIDwtIGFvdihIb3Vyc19TdHVkaWVkIH4gRGlzdGFuY2VfZnJvbV9Ib21lLCBkYXRhID0gc3R1ZGVudF9kYXRhKQ0Kc3VtbWFyeShhbm92YV9kaXN0YW5jZV9mcm9tX2hvbWUpDQpgYGANCg0KVGhlIEFOT1ZBIHRlc3Qgc2hvd3MgdGhhdCB0aGVyZSBpcyBubyBzaWduaWZpY2FudCBkaWZmZXJlbmNlIGluIHRoZSBhdmVyYWdlIG51bWJlciBvZiBob3VycyBzdHVkZW50cyBzdHVkeSBwZXIgd2VlayBiYXNlZCBvbiB0aGUgZGlzdGFuY2UgZnJvbSBob21lIHRvIHNjaG9vbCwgd2l0aCBhIHAtdmFsdWUgZ3JlYXRlciB0aGFuIDAuMDUuIFRoaXMgaW5kaWNhdGVzIHRoYXQgdGhlIGRpc3RhbmNlIGZyb20gaG9tZSB0byBzY2hvb2wgZG9lcyBub3QgaGF2ZSBhIHNpZ25pZmljYW50IGltcGFjdCBvbiB0aGUgbnVtYmVyIG9mIGhvdXJzIHN0dWRlbnRzIHN0dWR5IHBlciB3ZWVrLg0KDQojIyBBdmVyYWdlIE51bWJlciBvZiBIb3VycyBTdHVkZW50cyBTdHVkeSBwZXIgV2VlayAoR2VuZGVyIENhdGVnb3J5KQ0KDQpGaW5hbGx5LCB3ZSBleHBsb3JlIHRoZSBhdmVyYWdlIG51bWJlciBvZiBob3VycyBzdHVkZW50cyBzdHVkeSBwZXIgd2VlayBiYXNlZCBvbiBnZW5kZXIuDQoNCmBgYHtyfQ0KIyBTdW1tYXJ5IHN0YXRpc3RpY3MNCnN1bW1hcnkoc3R1ZGVudF9kYXRhJEhvdXJzX1N0dWRpZWRbc3R1ZGVudF9kYXRhJEdlbmRlciA9PSAiTWFsZSJdKQ0Kc3VtbWFyeShzdHVkZW50X2RhdGEkSG91cnNfU3R1ZGllZFtzdHVkZW50X2RhdGEkR2VuZGVyID09ICJGZW1hbGUiXSkNCmBgYA0KDQpUaGUgc3VtbWFyeSBzdGF0aXN0aWNzIG9mIHRoZSBhdmVyYWdlIG51bWJlciBvZiBob3VycyBzdHVkZW50cyBzdHVkeSBwZXIgd2VlayBiYXNlZCBvbiBnZW5kZXIgc2hvdyBubyBzaWduaWZpY2FudCBkaWZmZXJlbmNlcy4gV2Ugd2lsbCBub3cgdXNlIEFOT1ZBIHRvIHRlc3QgZm9yIGRpZmZlcmVuY2VzIGluIHN0dWR5IGhvdXJzIGJhc2VkIG9uIGdlbmRlci4gQnV0IGZpcnN0LCB3ZSBuZWVkIHRvIGNoZWNrIHRoZSBhc3N1bXB0aW9ucyBvZiBBTk9WQS4NCg0KYGBge3J9DQojIFNhbXBsZSB0aGUgZGF0YQ0KbWFsZV9kYXRhIDwtIHN0dWRlbnRfZGF0YSRIb3Vyc19TdHVkaWVkW3N0dWRlbnRfZGF0YSRHZW5kZXIgPT0gIk1hbGUiXVtzYW1wbGUoc3VtKHN0dWRlbnRfZGF0YSRHZW5kZXIgPT0gIk1hbGUiKSwgMTAwKV0NCmZlbWFsZV9kYXRhIDwtIHN0dWRlbnRfZGF0YSRIb3Vyc19TdHVkaWVkW3N0dWRlbnRfZGF0YSRHZW5kZXIgPT0gIkZlbWFsZSJdW3NhbXBsZShzdW0oc3R1ZGVudF9kYXRhJEdlbmRlciA9PSAiRmVtYWxlIiksIDEwMCldDQoNCiMgSGlzdG9ncmFtDQpwYXIobWZyb3cgPSBjKDEsIDIpKQ0KaGlzdChtYWxlX2RhdGEsIG1haW4gPSAiTWFsZSIsIHhsYWIgPSAiU3R1ZHkgSG91cnMiLCBjb2wgPSAic2t5Ymx1ZSIsIGJvcmRlciA9ICJibGFjayIpDQpoaXN0KGZlbWFsZV9kYXRhLCBtYWluID0gIkZlbWFsZSIsIHhsYWIgPSAiU3R1ZHkgSG91cnMiLCBjb2wgPSAic2t5Ymx1ZSIsIGJvcmRlciA9ICJibGFjayIpDQoNCiMgQ2hlY2sgYXNzdW1wdGlvbnMgb2YgQU5PVkENCnNoYXBpcm8udGVzdChtYWxlX2RhdGEpDQpzaGFwaXJvLnRlc3QoZmVtYWxlX2RhdGEpDQpgYGANCg0KQm90aCBoaXN0b2dyYW1zIGFuZCB0aGUgU2hhcGlyby1XaWxrIHRlc3Qgc2hvdyB0aGF0IHRoZSBkaXN0cmlidXRpb24gb2Ygc3R1ZHkgaG91cnMgaXMgYXBwcm94aW1hdGVseSBub3JtYWwgZm9yIGFsbCBzdHVkZW50cy4gV2Ugd2lsbCBub3cgdXNlIEFOT1ZBIHRvIHRlc3QgZm9yIGRpZmZlcmVuY2VzIGluIHN0dWR5IGhvdXJzIGJhc2VkIGdlbmRlci4NCg0KYGBge3J9DQojIEFOT1ZBIHRlc3QNCmFub3ZhX2dlbmRlciA8LSBhb3YoSG91cnNfU3R1ZGllZCB+IEdlbmRlciwgZGF0YSA9IHN0dWRlbnRfZGF0YSkNCnN1bW1hcnkoYW5vdmFfZ2VuZGVyKQ0KYGBgDQoNClRoZSBBTk9WQSB0ZXN0IHNob3dzIHRoYXQgdGhlcmUgaXMgbm8gc2lnbmlmaWNhbnQgZGlmZmVyZW5jZSBpbiB0aGUgYXZlcmFnZSBudW1iZXIgb2YgaG91cnMgc3R1ZGVudHMgc3R1ZHkgYmFzZWQgb24gZ2VuZGVyLg0KDQojIyBTdW1tYXJ5IG9mIEF2ZXJhZ2UgTnVtYmVyIG9mIEhvdXJzIFN0dWRlbnRzIFN0dWR5IHBlciBXZWVrDQoNCkluIHN1bW1hcnksIHRoZSBhdmVyYWdlIG51bWJlciBvZiBob3VycyBzdHVkZW50cyBzdHVkeSBwZXIgd2VlayBpcyBhcHByb3hpbWF0ZWx5IDE5Ljk4IGhvdXJzLiBUaGVyZSBhcmUgbm8gc2lnbmlmaWNhbnQgZGlmZmVyZW5jZXMgaW4gdGhlIGF2ZXJhZ2UgbnVtYmVyIG9mIGhvdXJzIHN0dWRlbnRzIHN0dWR5IHBlciB3ZWVrIGJhc2VkIG9uIHZhcmlvdXMgZmFjdG9ycyBzdWNoIGFzIHBhcmVudGFsIGludm9sdmVtZW50LCBhY2Nlc3MgdG8gcmVzb3VyY2VzLCBleHRyYWN1cnJpY3VsYXIgYWN0aXZpdGllcywgbW90aXZhdGlvbiBsZXZlbHMsIGludGVybmV0IGFjY2VzcywgZmFtaWx5IGluY29tZSwgdGVhY2hlciBxdWFsaXR5LCBzY2hvb2wgdHlwZSwgcGVlciBpbmZsdWVuY2UsIGxlYXJuaW5nIGRpc2FiaWxpdGllcywgcGFyZW50YWwgZWR1Y2F0aW9uIGxldmVscywgZGlzdGFuY2UgZnJvbSBob21lIHRvIHNjaG9vbCwgYW5kIEdlbmRlci4gVGhpcyBpbmRpY2F0ZXMgdGhhdCB0aGUgbnVtYmVyIG9mIGhvdXJzIHN0dWRlbnRzIHN0dWR5IHBlciB3ZWVrIGlzIGNvbnNpc3RlbnQgYWNyb3NzIGRpZmZlcmVudCBmYWN0b3JzLg0KDQojIFRoZSB2YXJpYXRpb24gaW4gYXR0ZW5kYW5jZSByYXRlcyBhY3Jvc3Mgc3R1ZGVudHMNCg0KTm93IHdlIGFuYWx5emUgdGhlIHZhcmlhdGlvbiBpbiBhdHRlbmRhbmNlIHJhdGVzIGFjcm9zcyBzdHVkZW50cy4NCg0KYGBge3J9DQojIFNhbXBsZSB0aGUgZGF0YQ0Kc2FtcGxlX2F0dGVuZGFuY2UgPC0gc3R1ZGVudF9kYXRhJEF0dGVuZGFuY2Vbc2FtcGxlKG5yb3coc3R1ZGVudF9kYXRhKSwgMTAwMCldDQoNCiMgU3VtbWFyeSBzdGF0aXN0aWNzIGZvciBhdHRlbmRhbmNlIHJhdGVzDQpzdW1tYXJ5KHNhbXBsZV9hdHRlbmRhbmNlKQ0KDQojIEhpc3RvZ3JhbSBvZiBhdHRlbmRhbmNlIHJhdGVzDQpoaXN0KHNhbXBsZV9hdHRlbmRhbmNlLCBtYWluID0gIkRpc3RyaWJ1dGlvbiBvZiBBdHRlbmRhbmNlIFJhdGVzIiwgeGxhYiA9ICJBdHRlbmRhbmNlIFJhdGUiLCBjb2wgPSAic2t5Ymx1ZSIsIGJvcmRlciA9ICJibGFjayIpDQpgYGANCg0KRnJvbSB0aGUgaGlzdG9ncmFtIHdlIGNhbiBzZWUgdGhhdCB0aGUgZGlzdHJpYnV0aW9uIG9mIGF0dGVuZGFuY2UgcmF0ZXMgaXMgYXBwcm94aW1hdGVseSB1bmlmb3JtLCByYW5naW5nIGZyb20gYXBwcm94aW1hdGVseSAqKmA2MCVgKiogdG8gKipgMTAwJWAqKi4gV2UgY2FuIHNlZSBvbmUgc2xpZ2h0bHkgaGlnaGVyIHBlYWsgYXJvdW5kICoqYDcwJWAqKiB0byAqKmA4MCVgKiouIEZyb20gdGhpcyB3ZSBjYW4gc2VlIHRoYXQgYXR0ZW5kYW5jZSByYXRlcyBhcmUgZXZlbmx5IGRpc3RyaWJ1dGVkIGFjcm9zcyBzdHVkZW50cy4gVGhlIGF2ZXJhZ2UgYXR0ZW5kYW5jZSByYXRlIGlzIGFwcHJveGltYXRlbHkgKipgNzkuNzUlYCoqLCB3aGljaCBpcyByZWxhdGl2ZWx5IGhpZ2guIFdlIG5vdyBpbnZlc3RpZ2F0ZSB0aGUgZmFjdG9ycyB0aGF0IG1heSBpbmZsdWVuY2UgYXR0ZW5kYW5jZSByYXRlcy4NCg0KIyMgQXR0ZW5kYW5jZSBSYXRlcyBieSBQYXJlbnRhbCBJbnZvbHZlbWVudA0KDQpXZSB3aWxsIG5vdyBleHBsb3JlIHRoZSBhdHRlbmRhbmNlIHJhdGVzIGJhc2VkIG9uIHBhcmVudGFsIGludm9sdmVtZW50IGxldmVscy4NCg0KYGBge3J9DQojIFN1bW1hcnkgc3RhdGlzdGljcyBmb3IgYXR0ZW5kYW5jZSByYXRlcyBieSBwYXJlbnRhbCBpbnZvbHZlbWVudA0Kc3VtbWFyeShzdHVkZW50X2RhdGEkQXR0ZW5kYW5jZVtzdHVkZW50X2RhdGEkUGFyZW50YWxfSW52b2x2ZW1lbnQgPT0gIkhpZ2giXSkNCnN1bW1hcnkoc3R1ZGVudF9kYXRhJEF0dGVuZGFuY2Vbc3R1ZGVudF9kYXRhJFBhcmVudGFsX0ludm9sdmVtZW50ID09ICJNZWRpdW0iXSkNCnN1bW1hcnkoc3R1ZGVudF9kYXRhJEF0dGVuZGFuY2Vbc3R1ZGVudF9kYXRhJFBhcmVudGFsX0ludm9sdmVtZW50ID09ICJMb3ciXSkNCmBgYA0KDQpUaGUgc3VtbWFyeSBzdGF0aXN0aWNzIG9mIHRoZSBhdHRlbmRhbmNlIHJhdGVzIGJhc2VkIG9uIHBhcmVudGFsIGludm9sdmVtZW50IGxldmVscyBzaG93IG5vIHNpZ25pZmljYW50IGRpZmZlcmVuY2VzLiBXZSB3aWxsIG5vdyB1c2UgQU5PVkEgdG8gdGVzdCBmb3IgZGlmZmVyZW5jZXMgaW4gYXR0ZW5kYW5jZSByYXRlcyBiYXNlZCBvbiBwYXJlbnRhbCBpbnZvbHZlbWVudCBsZXZlbHMuIEJ1dCBmaXJzdCwgd2UgbmVlZCB0byBjaGVjayB0aGUgYXNzdW1wdGlvbnMgb2YgQU5PVkEuDQoNCmBgYHtyfQ0KIyBTYW1wbGUgdGhlIGRhdGENCmhpZ2hfcGFyZW50YWxfaW52b2x2ZW1lbnRfYXR0ZW5kYW5jZSA8LSBzdHVkZW50X2RhdGEkQXR0ZW5kYW5jZVtzdHVkZW50X2RhdGEkUGFyZW50YWxfSW52b2x2ZW1lbnQgPT0gIkhpZ2giXVtzYW1wbGUoc3VtKHN0dWRlbnRfZGF0YSRQYXJlbnRhbF9JbnZvbHZlbWVudCA9PSAiSGlnaCIpLCAxMDApXQ0KbWVkaXVtX3BhcmVudGFsX2ludm9sdmVtZW50X2F0dGVuZGFuY2UgPC0gc3R1ZGVudF9kYXRhJEF0dGVuZGFuY2Vbc3R1ZGVudF9kYXRhJFBhcmVudGFsX0ludm9sdmVtZW50ID09ICJNZWRpdW0iXVtzYW1wbGUoc3VtKHN0dWRlbnRfZGF0YSRQYXJlbnRhbF9JbnZvbHZlbWVudCA9PSAiTWVkaXVtIiksIDEwMCldDQpsb3dfcGFyZW50YWxfaW52b2x2ZW1lbnRfYXR0ZW5kYW5jZSA8LSBzdHVkZW50X2RhdGEkQXR0ZW5kYW5jZVtzdHVkZW50X2RhdGEkUGFyZW50YWxfSW52b2x2ZW1lbnQgPT0gIkxvdyJdW3NhbXBsZShzdW0oc3R1ZGVudF9kYXRhJFBhcmVudGFsX0ludm9sdmVtZW50ID09ICJMb3ciKSwgMTAwKV0NCg0KIyBIaXN0b2dyYW0gb2YgYXR0ZW5kYW5jZSByYXRlcyBieSBwYXJlbnRhbCBpbnZvbHZlbWVudA0KcGFyKG1mcm93ID0gYygxLCAzKSkNCmhpc3QoaGlnaF9wYXJlbnRhbF9pbnZvbHZlbWVudF9hdHRlbmRhbmNlLCBtYWluID0gIkhpZ2ggUGFyZW50YWwgSW52b2x2ZW1lbnQiLCB4bGFiID0gIkF0dGVuZGFuY2UgUmF0ZSIsIGNvbCA9ICJza3libHVlIiwgYm9yZGVyID0gImJsYWNrIikNCmhpc3QobWVkaXVtX3BhcmVudGFsX2ludm9sdmVtZW50X2F0dGVuZGFuY2UsIG1haW4gPSAiTWVkaXVtIFBhcmVudGFsIEludm9sdmVtZW50IiwgeGxhYiA9ICJBdHRlbmRhbmNlIFJhdGUiLCBjb2wgPSAic2t5Ymx1ZSIsIGJvcmRlciA9ICJibGFjayIpDQpoaXN0KGxvd19wYXJlbnRhbF9pbnZvbHZlbWVudF9hdHRlbmRhbmNlLCBtYWluID0gIkxvdyBQYXJlbnRhbCBJbnZvbHZlbWVudCIsIHhsYWIgPSAiQXR0ZW5kYW5jZSBSYXRlIiwgY29sID0gInNreWJsdWUiLCBib3JkZXIgPSAiYmxhY2siKQ0KDQojIENoZWNrIGFzc3VtcHRpb25zIG9mIEFOT1ZBDQpzaGFwaXJvLnRlc3QoaGlnaF9wYXJlbnRhbF9pbnZvbHZlbWVudF9hdHRlbmRhbmNlKQ0Kc2hhcGlyby50ZXN0KG1lZGl1bV9wYXJlbnRhbF9pbnZvbHZlbWVudF9hdHRlbmRhbmNlKQ0Kc2hhcGlyby50ZXN0KGxvd19wYXJlbnRhbF9pbnZvbHZlbWVudF9hdHRlbmRhbmNlKQ0KYGBgDQoNCkFsbCB0aHJlZSBoaXN0b2dyYW1zIGFuZCB0aGUgU2hhcGlyby1XaWxrIHRlc3Qgc2hvdyB0aGF0IHRoZSBkaXN0cmlidXRpb24gb2YgYXR0ZW5kYW5jZSByYXRlcyBpcyBub3Qgbm9ybWFsIGZvciBhbGwgc3R1ZGVudHMuIFdlIHdpbGwgbm93IHVzZSBLcnVrc2FsLVdhbGxpcyB0ZXN0IHRvIHRlc3QgZm9yIGRpZmZlcmVuY2VzIGluIGF0dGVuZGFuY2UgcmF0ZXMgYmFzZWQgb24gcGFyZW50YWwgaW52b2x2ZW1lbnQgbGV2ZWxzLg0KDQpgYGB7cn0NCiMgS3J1a3NhbC1XYWxsaXMgdGVzdA0Ka3J1c2thbC50ZXN0KEF0dGVuZGFuY2UgfiBQYXJlbnRhbF9JbnZvbHZlbWVudCwgZGF0YSA9IHN0dWRlbnRfZGF0YSkNCmBgYA0KDQpUaGUgS3J1c2thbC1XYWxsaXMgdGVzdCBzaG93cyB0aGF0IHRoZXJlIGlzIG5vIHNpZ25pZmljYW50IGRpZmZlcmVuY2UgaW4gdGhlIGF2ZXJhZ2UgYXR0ZW5kYW5jZSByYXRlcyBiYXNlZCBvbiBwYXJlbnRhbCBpbnZvbHZlbWVudCBsZXZlbHMsIHdpdGggYSBwLXZhbHVlIGdyZWF0ZXIgdGhhbiAwLjA1LiBUaGlzIGluZGljYXRlcyB0aGF0IHBhcmVudGFsIGludm9sdmVtZW50IGRvZXMgbm90IGhhdmUgYSBzaWduaWZpY2FudCBpbXBhY3Qgb24gYXR0ZW5kYW5jZSByYXRlcy4NCg0KIyMgQXR0ZW5kYW5jZSBSYXRlcyBieSBBY2Nlc3MgdG8gUmVzb3VyY2VzDQoNCk5leHQsIHdlIGV4cGxvcmUgdGhlIGF0dGVuZGFuY2UgcmF0ZXMgYmFzZWQgb24gYWNjZXNzIHRvIHJlc291cmNlcy4NCg0KYGBge3J9DQojIFN1bW1hcnkgc3RhdGlzdGljcyBmb3IgYXR0ZW5kYW5jZSByYXRlcyBieSBhY2Nlc3MgdG8gcmVzb3VyY2VzDQpzdW1tYXJ5KHN0dWRlbnRfZGF0YSRBdHRlbmRhbmNlW3N0dWRlbnRfZGF0YSRBY2Nlc3NfdG9fUmVzb3VyY2VzID09ICJIaWdoIl0pDQpzdW1tYXJ5KHN0dWRlbnRfZGF0YSRBdHRlbmRhbmNlW3N0dWRlbnRfZGF0YSRBY2Nlc3NfdG9fUmVzb3VyY2VzID09ICJNZWRpdW0iXSkNCnN1bW1hcnkoc3R1ZGVudF9kYXRhJEF0dGVuZGFuY2Vbc3R1ZGVudF9kYXRhJEFjY2Vzc190b19SZXNvdXJjZXMgPT0gIkxvdyJdKQ0KYGBgDQoNClRoZSBzdW1tYXJ5IHN0YXRpc3RpY3Mgb2YgdGhlIGF0dGVuZGFuY2UgcmF0ZXMgYmFzZWQgb24gYWNjZXNzIHRvIHJlc291cmNlcyBzaG93IG5vIHNpZ25pZmljYW50IGRpZmZlcmVuY2VzLiBXZSB3aWxsIG5vdyB1c2UgQU5PVkEgdG8gdGVzdCBmb3IgZGlmZmVyZW5jZXMgaW4gYXR0ZW5kYW5jZSByYXRlcyBiYXNlZCBvbiBhY2Nlc3MgdG8gcmVzb3VyY2VzLiBCdXQgZmlyc3QsIHdlIG5lZWQgdG8gY2hlY2sgdGhlIGFzc3VtcHRpb25zIG9mIEFOT1ZBLg0KDQpgYGB7cn0NCiMgU2FtcGxlIHRoZSBkYXRhDQpoaWdoX2FjY2Vzc190b19yZXNvdXJjZXNfYXR0ZW5kYW5jZSA8LSBzdHVkZW50X2RhdGEkQXR0ZW5kYW5jZVtzdHVkZW50X2RhdGEkQWNjZXNzX3RvX1Jlc291cmNlcyA9PSAiSGlnaCJdW3NhbXBsZShzdW0oc3R1ZGVudF9kYXRhJEFjY2Vzc190b19SZXNvdXJjZXMgPT0gIkhpZ2giKSwgMTAwKV0NCm1lZGl1bV9hY2Nlc3NfdG9fcmVzb3VyY2VzX2F0dGVuZGFuY2UgPC0gc3R1ZGVudF9kYXRhJEF0dGVuZGFuY2Vbc3R1ZGVudF9kYXRhJEFjY2Vzc190b19SZXNvdXJjZXMgPT0gIk1lZGl1bSJdW3NhbXBsZShzdW0oc3R1ZGVudF9kYXRhJEFjY2Vzc190b19SZXNvdXJjZXMgPT0gIk1lZGl1bSIpLCAxMDApXQ0KbG93X2FjY2Vzc190b19yZXNvdXJjZXNfYXR0ZW5kYW5jZSA8LSBzdHVkZW50X2RhdGEkQXR0ZW5kYW5jZVtzdHVkZW50X2RhdGEkQWNjZXNzX3RvX1Jlc291cmNlcyA9PSAiTG93Il1bc2FtcGxlKHN1bShzdHVkZW50X2RhdGEkQWNjZXNzX3RvX1Jlc291cmNlcyA9PSAiTG93IiksIDEwMCldDQoNCiMgSGlzdG9ncmFtIG9mIGF0dGVuZGFuY2UgcmF0ZXMgYnkgYWNjZXNzIHRvIHJlc291cmNlcw0KcGFyKG1mcm93ID0gYygxLCAzKSkNCmhpc3QoaGlnaF9hY2Nlc3NfdG9fcmVzb3VyY2VzX2F0dGVuZGFuY2UsIG1haW4gPSAiSGlnaCBBY2Nlc3MgdG8gUmVzb3VyY2VzIiwgeGxhYiA9ICJBdHRlbmRhbmNlIFJhdGUiLCBjb2wgPSAic2t5Ymx1ZSIsIGJvcmRlciA9ICJibGFjayIpDQpoaXN0KG1lZGl1bV9hY2Nlc3NfdG9fcmVzb3VyY2VzX2F0dGVuZGFuY2UsIG1haW4gPSAiTWVkaXVtIEFjY2VzcyB0byBSZXNvdXJjZXMiLCB4bGFiID0gIkF0dGVuZGFuY2UgUmF0ZSIsIGNvbCA9ICJza3libHVlIiwgYm9yZGVyID0gImJsYWNrIikNCmhpc3QobG93X2FjY2Vzc190b19yZXNvdXJjZXNfYXR0ZW5kYW5jZSwgbWFpbiA9ICJMb3cgQWNjZXNzIHRvIFJlc291cmNlcyIsIHhsYWIgPSAiQXR0ZW5kYW5jZSBSYXRlIiwgY29sID0gInNreWJsdWUiLCBib3JkZXIgPSAiYmxhY2siKQ0KDQojIENoZWNrIGFzc3VtcHRpb25zIG9mIEFOT1ZBDQpzaGFwaXJvLnRlc3QoaGlnaF9hY2Nlc3NfdG9fcmVzb3VyY2VzX2F0dGVuZGFuY2UpDQpzaGFwaXJvLnRlc3QobWVkaXVtX2FjY2Vzc190b19yZXNvdXJjZXNfYXR0ZW5kYW5jZSkNCnNoYXBpcm8udGVzdChsb3dfYWNjZXNzX3RvX3Jlc291cmNlc19hdHRlbmRhbmNlKQ0KYGBgDQoNCkFsbCB0aHJlZSBoaXN0b2dyYW1zIGFuZCB0aGUgU2hhcGlyby1XaWxrIHRlc3Qgc2hvdyB0aGF0IHRoZSBkaXN0cmlidXRpb24gb2YgYXR0ZW5kYW5jZSByYXRlcyBpcyBub3Qgbm9ybWFsIGZvciBhbGwgc3R1ZGVudHMuIFdlIHdpbGwgbm93IHVzZSBLcnVrc2FsLVdhbGxpcyB0ZXN0IHRvIHRlc3QgZm9yIGRpZmZlcmVuY2VzIGluIGF0dGVuZGFuY2UgcmF0ZXMgYmFzZWQgb24gYWNjZXNzIHRvIHJlc291cmNlcy4NCg0KYGBge3J9DQojIEtydWtzYWwtV2FsbGlzIHRlc3QNCmtydXNrYWwudGVzdChBdHRlbmRhbmNlIH4gQWNjZXNzX3RvX1Jlc291cmNlcywgZGF0YSA9IHN0dWRlbnRfZGF0YSkNCmBgYA0KDQpUaGUgS3J1c2thbC1XYWxsaXMgdGVzdCBzaG93cyB0aGF0IHRoZXJlIGlzIG5vIHNpZ25pZmljYW50IGRpZmZlcmVuY2UgaW4gdGhlIGF2ZXJhZ2UgYXR0ZW5kYW5jZSByYXRlcyBiYXNlZCBvbiBhY2Nlc3MgdG8gcmVzb3VyY2VzLCB3aXRoIGEgcC12YWx1ZSBncmVhdGVyIHRoYW4gMC4wNS4gVGhpcyBpbmRpY2F0ZXMgdGhhdCBhY2Nlc3MgdG8gcmVzb3VyY2VzIGRvZXMgbm90IGhhdmUgYSBzaWduaWZpY2FudCBpbXBhY3Qgb24gYXR0ZW5kYW5jZSByYXRlcy4NCg0KIyMgQXR0ZW5kYW5jZSBSYXRlcyBieSBFeHRyYWN1cnJpY3VsYXIgQWN0aXZpdGllcw0KDQpOZXh0LCB3ZSBleHBsb3JlIHRoZSBhdHRlbmRhbmNlIHJhdGVzIGJhc2VkIG9uIHBhcnRpY2lwYXRpb24gaW4gZXh0cmFjdXJyaWN1bGFyIGFjdGl2aXRpZXMuDQoNCmBgYHtyfQ0KIyBTdW1tYXJ5IHN0YXRpc3RpY3MgZm9yIGF0dGVuZGFuY2UgcmF0ZXMgYnkgZXh0cmFjdXJyaWN1bGFyIGFjdGl2aXRpZXMNCnN1bW1hcnkoc3R1ZGVudF9kYXRhJEF0dGVuZGFuY2Vbc3R1ZGVudF9kYXRhJEV4dHJhY3VycmljdWxhcl9BY3Rpdml0aWVzID09ICJZZXMiXSkNCnN1bW1hcnkoc3R1ZGVudF9kYXRhJEF0dGVuZGFuY2Vbc3R1ZGVudF9kYXRhJEV4dHJhY3VycmljdWxhcl9BY3Rpdml0aWVzID09ICJObyJdKQ0KYGBgDQoNClRoZSBzdW1tYXJ5IHN0YXRpc3RpY3Mgb2YgdGhlIGF0dGVuZGFuY2UgcmF0ZXMgYmFzZWQgb24gcGFydGljaXBhdGlvbiBpbiBleHRyYWN1cnJpY3VsYXIgYWN0aXZpdGllcyBzaG93IG5vIHNpZ25pZmljYW50IGRpZmZlcmVuY2VzLiBXZSB3aWxsIG5vdyB1c2UgQU5PVkEgdG8gdGVzdCBmb3IgZGlmZmVyZW5jZXMgaW4gYXR0ZW5kYW5jZSByYXRlcyBiYXNlZCBvbiBwYXJ0aWNpcGF0aW9uIGluIGV4dHJhY3VycmljdWxhciBhY3Rpdml0aWVzLiBCdXQgZmlyc3QsIHdlIG5lZWQgdG8gY2hlY2sgdGhlIGFzc3VtcHRpb25zIG9mIEFOT1ZBLg0KDQpgYGB7cn0NCiMgU2FtcGxlIHRoZSBkYXRhDQpwYXJ0aWNpcGF0ZV9leHRyYWN1cnJpY3VsYXJfYXR0ZW5kYW5jZSA8LSBzdHVkZW50X2RhdGEkQXR0ZW5kYW5jZVtzdHVkZW50X2RhdGEkRXh0cmFjdXJyaWN1bGFyX0FjdGl2aXRpZXMgPT0gIlllcyJdW3NhbXBsZShzdW0oc3R1ZGVudF9kYXRhJEV4dHJhY3VycmljdWxhcl9BY3Rpdml0aWVzID09ICJZZXMiKSwgMTAwKV0NCmRvX25vdF9wYXJ0aWNpcGF0ZV9leHRyYWN1cnJpY3VsYXJfYXR0ZW5kYW5jZSA8LSBzdHVkZW50X2RhdGEkQXR0ZW5kYW5jZVtzdHVkZW50X2RhdGEkRXh0cmFjdXJyaWN1bGFyX0FjdGl2aXRpZXMgPT0gIk5vIl1bc2FtcGxlKHN1bShzdHVkZW50X2RhdGEkRXh0cmFjdXJyaWN1bGFyX0FjdGl2aXRpZXMgPT0gIk5vIiksIDEwMCldDQoNCiMgSGlzdG9ncmFtIG9mIGF0dGVuZGFuY2UgcmF0ZXMgYnkgZXh0cmFjdXJyaWN1bGFyIGFjdGl2aXRpZXMNCnBhcihtZnJvdyA9IGMoMSwgMikpDQpoaXN0KHBhcnRpY2lwYXRlX2V4dHJhY3VycmljdWxhcl9hdHRlbmRhbmNlLCBtYWluID0gIkV4dHJhY3VycmljdWxhciBBY3Rpdml0aWVzIiwgeGxhYiA9ICJBdHRlbmRhbmNlIFJhdGUiLCBjb2wgPSAic2t5Ymx1ZSIsIGJvcmRlciA9ICJibGFjayIpDQpoaXN0KGRvX25vdF9wYXJ0aWNpcGF0ZV9leHRyYWN1cnJpY3VsYXJfYXR0ZW5kYW5jZSwgbWFpbiA9ICJObyBFeHRyYWN1cnJpY3VsYXIgQWN0aXZpdGllcyIsIHhsYWIgPSAiQXR0ZW5kYW5jZSBSYXRlIiwgY29sID0gInNreWJsdWUiLCBib3JkZXIgPSAiYmxhY2siKQ0KDQojIENoZWNrIGFzc3VtcHRpb25zIG9mIEFOT1ZBDQpzaGFwaXJvLnRlc3QocGFydGljaXBhdGVfZXh0cmFjdXJyaWN1bGFyX2F0dGVuZGFuY2UpDQpzaGFwaXJvLnRlc3QoZG9fbm90X3BhcnRpY2lwYXRlX2V4dHJhY3VycmljdWxhcl9hdHRlbmRhbmNlKQ0KYGBgDQoNCkJvdGggaGlzdG9ncmFtcyBhbmQgdGhlIFNoYXBpcm8tV2lsayB0ZXN0IHNob3cgdGhhdCB0aGUgZGlzdHJpYnV0aW9uIG9mIGF0dGVuZGFuY2UgcmF0ZXMgaXMgbm90IG5vcm1hbCBmb3IgYWxsIHN0dWRlbnRzLiBXZSB3aWxsIG5vdyB1c2UgS3J1a3NhbC1XYWxsaXMgdGVzdCB0byB0ZXN0IGZvciBkaWZmZXJlbmNlcyBpbiBhdHRlbmRhbmNlIHJhdGVzIGJhc2VkIG9uIHBhcnRpY2lwYXRpb24gaW4gZXh0cmFjdXJyaWN1bGFyIGFjdGl2aXRpZXMuDQoNCmBgYHtyfQ0KIyBLcnVrc2FsLVdhbGxpcyB0ZXN0DQprcnVza2FsLnRlc3QoQXR0ZW5kYW5jZSB+IEV4dHJhY3VycmljdWxhcl9BY3Rpdml0aWVzLCBkYXRhID0gc3R1ZGVudF9kYXRhKQ0KYGBgDQoNClRoZSBLcnVza2FsLVdhbGxpcyB0ZXN0IHNob3dzIHRoYXQgdGhlcmUgaXMgbm8gc2lnbmlmaWNhbnQgZGlmZmVyZW5jZSBpbiB0aGUgYXZlcmFnZSBhdHRlbmRhbmNlIHJhdGVzIGJhc2VkIG9uIHBhcnRpY2lwYXRpb24gaW4gZXh0cmFjdXJyaWN1bGFyIGFjdGl2aXRpZXMsIHdpdGggYSBwLXZhbHVlIGdyZWF0ZXIgdGhhbiAwLjA1LiBUaGlzIGluZGljYXRlcyB0aGF0IHBhcnRpY2lwYXRpb24gaW4gZXh0cmFjdXJyaWN1bGFyIGFjdGl2aXRpZXMgZG9lcyBub3QgaGF2ZSBhIHNpZ25pZmljYW50IGltcGFjdCBvbiBhdHRlbmRhbmNlIHJhdGVzLg0KDQoNCg==